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
1
zizhoutong OP 我知道 this 的普通指向
|
2
guorui112 2019-02-07 14:13:57 +08:00
简单的方法记 this 的话,就是一句话,this 一般都是指向 . (点) 前的对象
|
3
zizhoutong OP |
4
rabbbit 2019-02-07 14:27:33 +08:00
|
5
azh7138m 2019-02-07 14:39:10 +08:00 via Android
emmmm,简单的说,这个是 member exp 的语法。
我们要实现,调用一个函数,并且指定 this,那么就没有什么好的办法,只能借助这个语法,将需要调用的函数存在一个对象上面,就是这个 ctx ( context.foo = this ),借助 member exp 来改变被调用函数的 this。 |
6
autoxbc 2019-02-07 15:16:11 +08:00 1
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 的最佳实践 |
7
zizhoutong OP @autoxbc 非常感谢。搞明白了,总是忘记 this 是在函数调用时才确定绑定的对象。
|
8
zizhoutong OP @rabbbit 懂了,谢谢!
|
9
zizhoutong OP @azh7138m 学了 python 和 java 再学 js 总觉得路坑坑洼洼的哈哈
|
10
azh7138m 2019-02-07 15:32:44 +08:00 via Android
@zizhoutong 你看,先学 C++就好了,感觉没模板的语言真简单(滑稽
|
11
fleam 2019-02-08 12:29:40 +08:00 via Android
以 fn 开始执行,fn 就是 this
|
12
zzjas98 2019-02-09 05:01:46 +08:00
有点没明白 delete context.fn 是在干什么, 可以解释一下 ma
|
13
zizhoutong OP @zzjas98 因为模拟 call 的逻辑是给传进来的 ctx 对象定义一个新方法 foo,然后把 fn 保存进去,执行完就要删掉,不然传进来的对象就会多一个 foo 属性
|
14
souljy 2019-02-09 13:41:25 +08:00
fn 的原型链指向 Function 的原型方法,因此 myCall 是 fn 的原型方法,所以 fn.myCall 中的 this 指的是 fn 本身
建议去了解一下原型链 最好了解一下 c++的链表 |
16
zipeijun 2019-02-09 13:59:45 +08:00 via iPhone
this 代表的就是当前执行环境、也就是 context。
有时候搞不清 this 指向的时候想想他的 context 是谁能解决很多问题。 |
17
zizhoutong OP @zipeijun 学到 vue 的时候,this 指向又变了,methods 里 click 的 this 指向 vue 实例,而不是调用 click 的标签。this 也太多变了
|