js中apply和call算是一個(gè)比較繞的方法,今天我就談?wù)勎覍?duì)它們的理解,錯(cuò)誤之處歡迎指正。
1,語法
/* call()方法 */
function.call(thisObj[, arg1[, arg2[, [,...argN]]]]);
/*apply()方法*/
function.apply(thisObj[, argArray])
call方法是傳入一個(gè)目標(biāo)對(duì)象thisObj,參數(shù)是以一個(gè)個(gè)逗號(hào)分隔的變量組成。call前面方法中this會(huì)指向thisObj。
apply方法是傳入一個(gè)目標(biāo)對(duì)象thisObj,參數(shù)是一個(gè)數(shù)組。apply前面方法中this會(huì)指向thisObj。
2,用法
1),不帶參數(shù)
function demo() {
//將參數(shù)轉(zhuǎn)化成數(shù)組
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]
可以看出,在不傳入?yún)?shù)的情況下,call和apply的表現(xiàn)一致,都是改變this的指向,然后調(diào)用方法。
為什么arguments可以轉(zhuǎn)化成數(shù)組呢?
因?yàn)?code>arguments是一個(gè)類數(shù)組,由于js是一種比較靈活的語言,所以可以對(duì)類數(shù)組進(jìn)行操作。(!注意:對(duì)于非類數(shù)組的對(duì)象,是不可以使用此方法的。)
下面是傳入?yún)?shù)1,打印arguments的結(jié)果

2),帶參數(shù)
不帶參數(shù)的
call,apply很容易理解,用法也很少,就是把類數(shù)組轉(zhuǎn)換成就數(shù)組。接下來看一下帶參數(shù)的用法,也是直接上代碼。
//計(jì)算數(shù)組中的最大值
var a = [1,2,3,2,1];
Math.max.apply(null,a); // 9 由于沒有對(duì)象調(diào)用Math.max方法,所以我們用null
Math.max.call(null,1,2,3,2,1); // 3
//合并數(shù)組
var b = [1,2];
var c = [3,4];
[].push.apply(b,c); // [1,2,3,4]
//[].push.apply(b,c)相當(dāng)于
for(i = 0;i<c.length;i++) {
b.push(c[i]);
}
在有參數(shù)的情況下,apply相當(dāng)于一個(gè)數(shù)組的遍歷方法,它會(huì)對(duì)數(shù)組中的每一項(xiàng)進(jìn)行操作,而call方法是將需要操作的變量以一個(gè)個(gè)的參數(shù)傳進(jìn)去。所以我們?cè)谛枰僮鲾?shù)組中的每一項(xiàng)的時(shí)候用apply,參數(shù)比較少的時(shí)候用call。
為了方便記憶,你可以這樣理解call,apply:
你使用一臺(tái)手機(jī),手機(jī)上有微信,微博,支付寶等軟件,call和apply都是打開軟件的操作,你打開他們,里面的個(gè)人信息就會(huì)指向你自己。