js中apply和call算是一個比較繞的方法,今天我就談談我對它們的理解,錯誤之處歡迎指正。
1,語法
/* call()方法 */
function.call(thisObj[, arg1[, arg2[, [,...argN]]]]);
/*apply()方法*/
function.apply(thisObj[, argArray])
call方法是傳入一個目標對象thisObj
,參數是以一個個逗號分隔的變量組成。call前面方法中this會指向thisObj
。
apply方法是傳入一個目標對象thisObj
,參數是一個數組。apply前面方法中this會指向thisObj
。
2,用法
1),不帶參數
function demo() {
//將參數轉化成數組
var arr = Array.prototype.slice.call(arguments);
//或者
var arr1 = Array.prototype.slice.apply(arguments);
//或者
var arr2 = [].slice.call(arguments);
//或者
var arr3 = [].slice.apply(arguments);
//[].slice方法要比Array.prototupe.slice的效率更高
console.log(arr,arr1,arr2,arr3);
}
demo(1,2); // [1, 2] [1, 2] [1, 2] [1, 2]
可以看出,在不傳入參數的情況下,call
和apply
的表現一致,都是改變this的指向,然後調用方法。
爲什麼arguments
可以轉化成數組呢?
因爲arguments
是一個類數組,由於js
是一種比較靈活的語言,所以可以對類數組進行操作。(!注意:對於非類數組的對象,是不可以使用此方法的。)
下面是傳入參數1,打印arguments的結果
2),帶參數
不帶參數的
call
,apply
很容易理解,用法也很少,就是把類數組轉換成就數組。接下來看一下帶參數的用法,也是直接上代碼。
//計算數組中的最大值
var a = [1,2,3,2,1];
Math.max.apply(null,a); // 9 由於沒有對象調用Math.max方法,所以我們用null
Math.max.call(null,1,2,3,2,1); // 3
//合併數組
var b = [1,2];
var c = [3,4];
[].push.apply(b,c); // [1,2,3,4]
//[].push.apply(b,c)相當於
for(i = 0;i<c.length;i++) {
b.push(c[i]);
}
在有參數的情況下,apply相當於一個數組的遍歷方法,它會對數組中的每一項進行操作,而call方法是將需要操作的變量以一個個的參數傳進去。所以我們在需要操作數組中的每一項的時候用apply,參數比較少的時候用call。
爲了方便記憶,你可以這樣理解call
,apply
:
你使用一臺手機,手機上有微信,微博,支付寶等軟件,call和apply都是打開軟件的操作,你打開他們,裏面的個人信息就會指向你自己。