JavaScript函數,事實上是對象,他們均有兩個非繼承而來的方法,它們就是 call() apply()
和
,它們在函數中扮演着什麼樣的角色呢?
它們倆其實功能是一樣一樣的,都是在特定的作用域中調用函數,就等于設定函數體中
this
對象的值。但是,它們也有各自的特點。 可以傳多個參數,第一個參數是一個對象,後面的參數就是該函數的參數。
call()
最多隻能傳兩個參數,第一個參數是一個對象,第二個參數是該函數參數組成的數組,也可以是
apply()
對象。
arguments
說了這麼多文绉绉的東西,舉個栗子吧~~~
var name = "李四";
var zhangsan = {
name: "張三",
age: 18
};
function getName(){
return this.name;
}
function add(a,b){
return this.age+a+b;
}
console.log(getName()); // "李四"
console.log(getName.call(zhangsan)); // "張三"
console.log(add.apply(zhangsan,[2,3])); // 23
第一個輸出
"李四"
,這個很好了解,因為
getName()
如果直接執行的話,其
this
指針指向的是
window
,因為
getName()
屬于全局函數;
第二個輸出
"張三"
,根據上面講的
call()
的作用可知,此時
getName()
中的
this
指針指向不再是
window
,而改成了
zhangsan
,是以自然
getName()
執行後傳回的是
zhangsan.name
;
第三個輸出
23
apply()
作用與
call()
作用一緻可知,此時
add()
this
指針指向
zhangsan
,而
add
參數中的
a
b
則一 一對應數組
[2,3]
中的每一項,是以
add()
zhangsan.age+2+3
,計算結果為
23
。
等等,上面提到的
arguments
是什麼鬼?在例子中怎麼沒有出現?
其實嘛,
arguments
是個一種長得很像數組的類數組對象,它也具有
length
屬性,卻不具有數組的其他方法,是以它并不是數組,可以看做是由函數實參組成的一個集合。
說了這麼多,
call()
apply()
到底在實際項目中有什麼用呢?
我個人覺得,這兩者最大作用莫過于實作對象間的繼承了。比如上面提到的那個
arguments
,它不是數組,但是如果想将它變為數組,這該如何實作?
這時
call()
就可以派上用場了。通過
Array.prototype.slice.call(arguments)
就可以将
arguments
這樣的類數組轉成真正的數組。
再比如,通過
Math.max.apply(null,arr)
這樣的方式可以取得一個
arr
數組中的最大值。這是因為
Math.max()
如果直接調用的話是不能夠直接傳入數組的,必須要一個個參數傳進去,是以通過
apply()
可以很友善的實作取數組最大值的功能。
本文重點總結
① call() 與 apply() 功能基本一緻,都是用于改變函數作用域
② call() 可以傳多個參數,第一個參數後的所有參數為該函數的參數;apply() 隻能傳兩個參數, 且第二個參數是該函數的參數所組成的數組或arguments對象