call()
方法的做用和apply()
方法相似,區別就是call()方法接受的是參數列表,而apply()方法接受的是一個參數數組。java
call()
方法使用一個指定的 this 值和單獨給出的一個或多個參數來調用一個函數。算法
fun.call(thisArg, arg1, arg2, ...)
複製代碼
參數數組
thisArg
bash
在 fun
函數運行時指定的 this
值。if(thisArg == undefined|null) this = window,if(thisArg == number|boolean|string) this == new Number()|new Boolean()| new String()
網絡
arg1
, arg2
, ...
數據結構
指定的參數列表。app
在該例子中,子構造函數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
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。
在下面的例子中,咱們調用了 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()
方法調用一個具備給定this
值的函數,以及做爲一個數組(或相似數組對象)提供的參數。
func.apply(thisArg, [argsArray])
參數
thisArg
可選的。在 func
函數運行時使用的 this
值。請注意,this
可能不是該方法看到的實際值:若是這個函數處於非嚴格模式下,則指定爲 null
或 undefined
時會自動替換爲指向全局對象,原始值會被包裝。
argsArray
可選的。一個數組或者類數組對象,其中的數組元素將做爲單獨的參數傳給 func
函數。若是該參數的值爲 null
或 undefined
,則表示不須要傳入任何參數。從ECMAScript 5
開始可使用類數組對象。
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"]
複製代碼
咱們可使用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]
複製代碼
call
、apply
的做用相同,即指定的 this 值和單獨給出的一個或多個參數來調用一個函數。