JS 的 call、apply 函數

二者的基本用法

call()方法的做用和 apply() 方法相似,區別就是call()方法接受的是參數列表,而apply()方法接受的是一個參數數組java

call

call() 方法使用一個指定的 this 值和單獨給出的一個或多個參數來調用一個函數。算法

call的語法

fun.call(thisArg, arg1, arg2, ...)
複製代碼

參數數組

  • thisArgbash

    fun 函數運行時指定的 this 值。if(thisArg == undefined|null) this = window,if(thisArg == number|boolean|string) this == new Number()|new Boolean()| new String()網絡

  • arg1, arg2, ...數據結構

    指定的參數列表。app

call的應用

使用 call 方法調用父構造函數實現繼承

在該例子中,子構造函數Sun()經過調用父構造函數Father()call 方法來實現繼承,此時Sun()函數中擁有了Father()函數中的屬性。函數

function Father(name,age){
	this.name = name;
	this.age = age;
	this.book=['數據結構','計算機網絡','算法']
	console.log('1.執行到Father---名字:'+this.name+'; 年齡:'+this.age+' 書籍:'+this.book);

}
function Sun(name,age){
	Father.call(this,name,age);
	this.subject = '軟件專業';
	console.log('2.執行到Sun---專業:'+this.subject);
}
var sun = new Sun('gxm','20');
	sun.book.push('javaScript');
	console.log('3.改變sun.book:'+sun.book);
	
var sun2 = new Sun('xz','22');
複製代碼

運行結果ui

1.執行到Father---名字:gxm; 年齡:20 書籍:數據結構,計算機網絡,算法
2.執行到Sun---專業:軟件專業
3.改變sun.book:數據結構,計算機網絡,算法,javaScript

1.執行到Father---名字:xz; 年齡:22 書籍:數據結構,計算機網絡,算法
2.執行到Sun---專業:軟件專業
4.查看sun2.book:數據結構,計算機網絡,算法
複製代碼

從這個運行結果也能夠看出,new出來的實例對其繼承而來的屬性進行改變,對於原函數來講並無改變。this

使用 call 方法調用函數而且指定上下文的 this

function play() {
  var reply = [this.player, '打', this.playName,'打了',this.playTimes].join(' ');
  console.log(reply);
}

var obj = {
  player: 'gxm',playName: '羽毛球', playTimes: '1小時'
};

play.call(obj); //gxm 打 羽毛球 打了 1小時
複製代碼

若是直接運行play()函數,結果就只會是打 打了。但指定了上下文就不同了,play.call(obj)就是將play()函數的上下文從全局的window指定到obj對象上了。因此運行出來的結果過成爲gxm 打 羽毛球 打了 1小時

思考下面的代碼之中有幾個this:

function foo() {
  return () => {
    return () => {
      return () => {
        console.log('id:', this.id);
      };
    };
  };
}

var f = foo.call({id: 1});

var t1 = f.call({id: 2})()(); // id: 1
var t2 = f().call({id: 3})(); // id: 1
var t3 = f()().call({id: 4}); // id: 1
複製代碼

上面代碼之中,只有一個this,就是函數foo的this,因此t一、t二、t3都輸出一樣的結果。由於全部的內層函數都是箭頭函數,都沒有本身的this,它們的this其實都是最外層foo函數的this。

使用 call 方法調用函數而且不指定第一個參數(argument)節

在下面的例子中,咱們調用了 display 方法,但並無傳遞它的第一個參數。若是沒有傳遞第一個參數,this 的值將會被綁定爲全局對象。

var sData = 'Wisen';

function display() {
  console.log('sData value is %s ', this.sData);
}

display.call();  // sData value is Wisen
複製代碼

注意:在嚴格模式下,this 的值將會是 undefined。見下文。

'use strict';

var sData = 'Wisen';

function display() {
  console.log('sData value is %s ', this.sData);
}

display.call(); // Cannot read the property of 'sData' of undefined
複製代碼

apply

apply()方法調用一個具備給定this值的函數,以及做爲一個數組(或相似數組對象)提供的參數。

apply語法

func.apply(thisArg, [argsArray])

參數

  • thisArg

    可選的。在 func 函數運行時使用的 this 值。請注意,this可能不是該方法看到的實際值:若是這個函數處於非嚴格模式下,則指定爲 nullundefined 時會自動替換爲指向全局對象,原始值會被包裝。

  • argsArray

    可選的。一個數組或者類數組對象,其中的數組元素將做爲單獨的參數傳給 func 函數。若是該參數的值爲 nullundefined,則表示不須要傳入任何參數。從ECMAScript 5 開始可使用類數組對象。

apply的應用

apply實現繼承

function superType() {
    this.color = ['red','blue','yellow']
}
function subType() {
    //---繼承了superType---
    superType.applay(this);
    //superType.call(this);
}
var instance1 = new subType();
instance1.color.push('green');
console.log('instance1.color:', instance1.color);
//instance1.color: (4) ["red", "blue", "yellow", "green"]
複製代碼

用 apply 將數組添加到另外一個數組

咱們可使用push將元素追加到數組中。而且,由於push接受可變數量的參數,咱們也能夠一次推送多個元素。

可是,若是咱們傳遞一個數組來推送,它實際上會將該數組做爲單個元素添加,而不是單獨添加元素,所以咱們最終獲得一個數組內的數組。若是那不是咱們想要的怎麼辦?在這種狀況下,concat確實具備咱們想要的行爲,但它實際上並不附加到現有數組,而是建立並返回一個新數組。

可是咱們想要附加到咱們現有的陣列......那麼如今呢? 寫一個循環?固然不是嗎?

apply來幫你!

var array = ['a', 'b'];
var elements = [0, 1, 2];
array.push.apply(array, elements);
console.info(array); // ["a", "b", 0, 1, 2]
複製代碼

相同點

callapply的做用相同,即指定的 this 值和單獨給出的一個或多個參數來調用一個函數。

相關文章
相關標籤/搜索