Apply的理解
Apply 和 Call一样在 函数调用的时候会改变函数内的this指向,让this变成 Apply或Call的第一个参数。
举个例子:
var ObjEngineer = { name:'程序员努力的一天', age:19 }; function fn2() { console.log(this.name); } fn2.Apply(ObjEngineer ) 输出: 程序员努力的一天
是不是感觉 this.name 的值被 ObjEnginner中的 name给覆盖了呢,就是的。
解刨一下原理:
自定一个 myCall吧,把 myCall 挂载到 Function上,这样每个函数都可以使用myCall
Function.prototype.myCall = function(context){ context.fn = this; //这里的this是指谁调用 myCall 就指向谁,比如: b.myCall ,这个 this 就指向 b context.fn(); delete context.fn; }
上面代码是先给context对象添加一个 fn的函数,把外面调用 myCall的函数传给 context.fn, 当 context.fn() 执行完之后就可以把他删除掉了不用了。
如果带有参数的方式呢?
升级一下
Function.prototype.myCall = function(context,arr){ let fn = Symbol() //ES6中的Symbol唯一性,就是防止 this中的函数明和 自定的函数明(fn)重名 context[fn] = this; //this 指向调用者,比如下面的fn2 context[fn](...arr); //传递参数 delete context[fn]; } var ObjEngineer = { name:'程序员努力的一天', age:19 }; function fn2(age,email) { console.log(this.name+" 年龄:"+age+" Email: "+email); } fn2.myCall(ObjEngineer,[19,'189@qq.com']) //第二个参数接收数组方式
输出:
程序员努力的一天 年龄:19 Email: 189@qq.com
如果调用的函数有返回值咋办?
在升级一下
Function.prototype.myCall = function(context,arr){ let fn = Symbol() //ES6中的Symbol唯一性,就是防止 this中的函数明和 自定的函数明(fn)重名 context[fn] = this; let res = context[fn](...arr); //传递参数 delete context[fn]; return res; } var ObjEngineer = { name:'程序员努力的一天', age:19 }; //带有返回值的 function fn2(age,email) { console.log(this.name+" 年龄:"+age+" Email: "+email); return {age,email} } let res = fn2.myCall(ObjEngineer,[19,'189@qq.com']) //第二个参数接收数组方式 console.log(res);
输出:
程序员努力的一天 年龄:19 Email: 189@qq.com
{age: 19, email: '189@qq.com'}
上面的myCall还不够完善,当没有 obj 和 arr 参数的时候就有问题,在完善一下。
Function.prototype.myCall = function(context,arr){ context = context || window //没有contenxt的时候,就指向window let fn = Symbol() //ES6中的Symbol唯一性,就是防止 this中的函数明和 自定的函数明(fn)重名 context[fn] = this; let res = !arr ? context[fn]() : context[fn](...arr); //传递参数,没有参数的时候也要处理一下 delete context[fn]; return res; }
参考:https://www.bilibili.com/video/BV1s3411g7gU/?spm_id_from=333.337.search-card.all.click&vd_source=02f2aad32c21e62474c9d52666b96f92
https://www.cnblogs.com/GoodPingGe/p/16145199.html