難兄難弟
我是js里的call方法,我和apply方法是難兄難弟。為什么這么說呢,因為很多前端小白看到咱倆就犯怵: "WTF!這是什么方法,根本看不懂啊!"然后去谷歌去百度,回來還是:"WTF!還是沒懂!"。然后就把咱倆丟在一邊不管了,心想:"哎,能不用就不用吧,反正也不見得用得著"。
借過來玩一玩
其實只要你認真的研究一下, 就會發現我和我哥們一點也不難。有些地方沒有咱倆還真不行。要說咱倆有啥用,我管咱倆的功能叫借過來玩一玩
。你看下面的例子啊:
let cat = {
food: 'fish',
eat: function() {
console.log('I want to eat ' + this.food);
},
sleep: function(time) {
console.log('I sleep' + time);
}
}
let dog = {
food: 'bone',
playBall: function() {
console.log('I am a doggy, I love playing ball');
}
}
dog.playBall(); //I am a doggy, I love playing ball
cat.eat(); //I want to eat fish
cat.eat.call(dog); //I want to eat bone
喵星人那里定義了eat方法,而汪星人里邊只定義了playBall方法,懶惰的汪星人不想在自己內部再定義一個重復的eat方法,但是又想吃吃吃,那怎么辦呢?
當然就是通過我call方法來找喵星人把eat方法借過來玩一玩
啦。所以呢:
cat.eat.call(dog);
的意思就是:喵哥!你的eat方法借dog玩一玩唄!你那個eat方法里的this現在指向了dog了啊!
這下你明白了為啥我的功能是借過來玩一玩
了吧:
1.沒有的方法我去別人那里借。
2.我可以改變被調用方法內部的this指向, this指向第一個參數。
除此之外,你可能會問了,假如我要調用的函數要接收參數,要怎么辦呢?那么可以用到我call方法接收的第2,3,4...個參數了!
cat.sleep.call(dog, 'all day'); //I sleep all day
我和我哥們apply的區別
我和我哥們apply區別很小很小,因為咱倆的主要功能都是一樣的,都是借方法過來玩一玩外加改變this的指向,咱倆唯一的不同在于:
對于要借過來玩一玩的函數:
function myFunction(arg1, arg2, arg3, arg4) {
console.log(arg1);
console.log(arg2);
console.log(arg3);
console.log(arg4);
}
我call的使用方法是myFunction.call(null, '1', '2', '3', '4')
而apply的使用方法是myFunction.apply(null, ['1', '2', '3', '4'])
看出來了么,apply這哥們有強迫癥!他要把傳進去的參數用數組包起來!而我就是一個一個往里傳。你要是怕記混咱倆,你就這么記: 我是call,call就是打電話啊,打電話不得一個一個打嗎,所以我的參數是一個個獨立的。
這區別有啥用啊?
你可能又要問了:既然你倆區別這么小,而且看你上面的例子,既能用call又能用apply,那你倆這區別有啥用啊?
嘿嘿嘿,當然有用啦,看我給你舉個栗子啊:
//這個函數熟悉吧?求傳入參數的最大值
Math.max(1, 2, 3); //3
如果你是想求一個數組中的最大值, 咋辦?把數組傳入Math.max?當然不行,不信的話你可以試一下。這個時候我call方法就無能為力了,只能讓apply幫你了:
let myArray = [1, 2, 3];
Math.max.apply(null, myArray);
最后
我們這對難兄難弟其實一點也不難啊!(╯﹏╰)