关于模拟 call 函数中 this 指向问题

2019-02-07 12:54:01 +08:00
 zizhoutong
let obj = {name:'zzt'};                         
function fn() {                                 
    console.log(this.name);                     
}                                               
Function.prototype.MyCall = function (context) {
    context.foo = this;                         
    context.foo();                              
    delete context.fn;                          
};                                              
fn.MyCall(obj);

这段代码中,为什么 this 代表的是 fn 函数,传递给 context

2269 次点击
所在节点    程序员
17 条回复
zizhoutong
2019-02-07 13:22:21 +08:00
我知道 this 的普通指向
guorui112
2019-02-07 14:13:57 +08:00
简单的方法记 this 的话,就是一句话,this 一般都是指向 . (点) 前的对象
zizhoutong
2019-02-07 14:25:23 +08:00
@guorui112 可是我不太明白
context.foo = this
这一句是什么意思呢
rabbbit
2019-02-07 14:27:33 +08:00
每周都能看到关于 this 的问题...
azh7138m
2019-02-07 14:39:10 +08:00
emmmm,简单的说,这个是 member exp 的语法。
我们要实现,调用一个函数,并且指定 this,那么就没有什么好的办法,只能借助这个语法,将需要调用的函数存在一个对象上面,就是这个 ctx ( context.foo = this ),借助 member exp 来改变被调用函数的 this。
autoxbc
2019-02-07 15:16:11 +08:00
this 就是语法糖,用来访问宿主的成员函数时,隐式把宿主传递给成员函数

fn.MyCall(obj) 这一句,MyCall 在 fn 的原型链上,所以 fn 是 MyCall 的宿主
MyCall 调用时,fn 作为 this 传递给 MyCall,并在 context.foo = this 这一句把 fn(this) 保存到 context.foo
context.foo 执行时,context 就是 foo(fn) 的宿主,context(obj) 作为 this 传递给 fn

call,apply,bind 本来就是糟糕的设计,ES6 中的双冒号语法 :: 才是 this 的最佳实践
zizhoutong
2019-02-07 15:26:22 +08:00
@autoxbc 非常感谢。搞明白了,总是忘记 this 是在函数调用时才确定绑定的对象。
zizhoutong
2019-02-07 15:26:52 +08:00
@rabbbit 懂了,谢谢!
zizhoutong
2019-02-07 15:27:50 +08:00
@azh7138m 学了 python 和 java 再学 js 总觉得路坑坑洼洼的哈哈
azh7138m
2019-02-07 15:32:44 +08:00
@zizhoutong 你看,先学 C++就好了,感觉没模板的语言真简单(滑稽
fleam
2019-02-08 12:29:40 +08:00
以 fn 开始执行,fn 就是 this
zzjas98
2019-02-09 05:01:46 +08:00
有点没明白 delete context.fn 是在干什么, 可以解释一下 ma
zizhoutong
2019-02-09 05:18:56 +08:00
@zzjas98 因为模拟 call 的逻辑是给传进来的 ctx 对象定义一个新方法 foo,然后把 fn 保存进去,执行完就要删掉,不然传进来的对象就会多一个 foo 属性
souljy
2019-02-09 13:41:25 +08:00
fn 的原型链指向 Function 的原型方法,因此 myCall 是 fn 的原型方法,所以 fn.myCall 中的 this 指的是 fn 本身
建议去了解一下原型链 最好了解一下 c++的链表
souljy
2019-02-09 13:42:29 +08:00
@zzjas98 感觉应该是 delete context.foo 才对的
zipeijun
2019-02-09 13:59:45 +08:00
this 代表的就是当前执行环境、也就是 context。
有时候搞不清 this 指向的时候想想他的 context 是谁能解决很多问题。
zizhoutong
2019-02-09 14:11:02 +08:00
@zipeijun 学到 vue 的时候,this 指向又变了,methods 里 click 的 this 指向 vue 实例,而不是调用 click 的标签。this 也太多变了

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/533300

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX