call && apply && bind 用法區別小結面試
故事開頭,恰逢其時,就行系統的總結下 call
apply
bind
,這也是面試官常常問的小程序
你知道this指向的問題嗎,簡單說說你的理解?
--------------------------------------------------
我……
複製代碼
簡潔的貼上一段小程序的代碼數組
/** * 生命週期函數--監聽頁面加載 */
onLoad: function(options) {
console.log("接收url中的參數",options)
AuthApis.voteItemListRouter(
options
).then((res) =>{
console.log(res.data.voteContent)
let voteItemListvote = res.data
let voteItemListdetail = res.data.voteContent
console.log("data",voteItemListvote)
this.setData({
voteItemvote:voteItemListvote,
voteItemList: voteItemListdetail
})
console.log('test1',voteItemListdetail,voteItemListvote)
console.log('test2',voteItemvote,voteItemList)
})
},
複製代碼
如上的代碼看起來也沒有什麼問題,控制檯輸出便有點問題,也趁此機會總結一下三者的區別bash
// 定義上下文
let ctx = {
name: `yayxs`
};
// 定義函數
const fn = function(age, sex) {
console.log(`${this.name}-${age}-${sex}`);
};
// 調用函數
fn(18, `男`);
複製代碼
const fnCall = function(age, sex) {
console.log(`call-${this.name}-${age}-${sex}`);
};
// fnCall(18, `男`); // call-undefined-18-男
fnCall.call(ctx, 18, `男`); // call-yayxs-18-男
// 總結:改變this指向,執行函數,參數列表傳入
複製代碼
const fnBind = function(age, sex) {
console.log(`bind-${this.name}-${age}-${sex}`);
};
fnBind.bind(ctx); // 沒有輸出
const res = fnBind.bind(ctx);
console.log(res); // [Function: bound fnBind]
res(18, "男"); // bind-yayxs-18-男
複製代碼
假若本身手寫代碼實現call
與 apply
app
call
Function.prototype.myCall = function(ctx, ...params) {
// console.log(ctx); { name: 'yayxs' }
// console.log(...params); 18 男
if (typeof ctx === "object") {
ctx = ctx || window;
} else {
ctx = null;
}
// 臨時方法名
let funcName = Symbol();
// console.log(funcName);
ctx[funcName] = this;
// console.log(this); [Function: testFn]
ctx[funcName](...params);
delete ctx[funcName];
};
複製代碼
整體來講,call
apply
bind
三個函數的做用都是用來改變this
的指向。目前的 js 還存在回調函數這一現象,尤爲在框架中一些異步回調
也是十分的常見,不免this
會迷失方向。三者既有不一樣也有類似框架
方法名 | 做用 | 是否自動執行 | 參數列表 |
---|---|---|---|
call | 改變 this 指向 | 自動執行 | 通常列表 |
apply | 改變 this 指向 | 自動執行 | 數組形式 |
bind | 改變 this 指向 | 返回一個函數 | 通常列表 |