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 指向 | 返回一个函数 | 通常列表 |