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

 

posted @ 2022-09-30 16:51  幽冥狂_七  阅读(38)  评论(0编辑  收藏  举报