谢谢上一个帖子各位大牛细心解答,是应该把 this 分开看。然后我看 you dont know js,先把 this 搞懂,里面说的 this 的会突然指向 window 的变量,结合楼内大神的答案,其实可以用 window 解释,然后我遇到了回调函数 this 的下面问题:
var name = "global";
var obj = {
name: "Yes",
getName: function() {
console.log(this.name);
}
}
function doo(f) {
f();
}
doo(obj.getName) //"global"
至少这个例子我可以理解为 obj.getName 的调用点再 doo 函数里,所以 this 应该指向这个,而调用这个函数可以解释为 window.doo(obj.getName),doo 的 this 指向 window,所以最终的 this 指向 window。那如果我用一个有 this 的对象来调用呢。代码如下:
var name = "global";
var obj = {
name: "Yes",
getName: function() {
console.log(this.name);
}
}
var obj2 = {
name: "Yes2",
getName: function(f) {
f();
}
}
obj2.getName(obj.getName) //"global"
发现这个 this 还是指向 window,有点想不通。。。
1
UncleRiver 2017-05-22 12:57:03 +08:00
参考一下这个:
http://stackoverflow.com/questions/7043509/this-inside-object > Javascript has no block scope, only function scope |
2
whimsySun 2017-05-22 13:08:43 +08:00
函数被传递时没有通过 bind 方法指定 this,this 指向其调用方的上下文,调用方你可以理解为 ${invoke}.${function}. 如果 invoke 没有指定,就是 this 就指向 global。
上面的例子: 调用 obj2.getName 时候 getName 的调用方就是 obj2,this 既 obj2. obj.getName 本传递后,仅做为一个函数传递,使用的时候也没有指定调用方,既 this 为 global 如果你需要 obj2.getName(obj.getName) 输出 “ Yes ”, 通过 obj2.getName(obj.getName.bind(obj)) 如果你需要 obj2.getName(obj.getName) 输出 ‘ Yes2 ’, 修改 obj2,`obj2.getName = function(f) { f.apply(this) }` |
3
whimsySun 2017-05-22 13:10:53 +08:00
@UncleRiver 和楼主的例子是两种情况
|
4
ericls 2017-05-22 13:11:18 +08:00
@UncleRiver `let` and `const` are block scoped
|
5
otakustay 2017-05-22 13:27:09 +08:00
只看调用不看怎么定义和怎么传参,你只要看到 doo 里是 f()(函数调用),那么这个 f 只要没 bind,无论它怎么定义的怎么传进来的,它的 this 都是 global,和 doo 的 this 是啥以及这个 f 怎么来都没关系
|
6
cheroky OP @whimsySun 感谢热心回答。但是我还有问题是这个函数作为对象的方法被调用,不是应该指向该对象么?而且这个函数既不是全局函数。而且用 obj2 调用,为什么不指向 obj2?
|
7
lijsh 2017-05-22 13:33:08 +08:00 1
|
8
wodewone 2017-05-22 13:42:24 +08:00
js 执行要看它的运行环境而不是它的初始环境
|
9
xilixjd 2017-05-22 13:43:58 +08:00
你确定你看完了 u don't know 吗。。
this 的指向是看在哪调用的,好像有 4 种调用形式 你这个例子跟第一种是一样的 |
10
sensui7 2017-05-22 14:11:06 +08:00 1
> 至少这个例子我可以理解为 obj.getName 的调用点再 doo 函数里...
你理解错了, 这里不存在 obj.getName 的调用, 你只不过是把 obj.getName 赋值给了形式参数f,你调用的是形参f. 形参f是什么, 是函数调用阿. |
11
ChefIsAwesome 2017-05-22 14:13:56 +08:00
别想了,你不用 this 就完事了。
|
12
cheroky OP |
13
bramblex 2017-05-22 15:16:48 +08:00
const f = function () {console.log(this)}
f() // => window / global const aaa = {} aaa.f = f aaa.f() // => aaa 这个你能理解嘛? f() 等效于 f.apply(window/global) |
14
bramblex 2017-05-22 15:18:10 +08:00
上面的要是你都理解,把他反过来你就不会了?
const aaa = {f: function() {console.log(this)}} const f = aaa.f f() |
15
cheroky OP @bramblex 这个我能理解,我的理解是
f=aaa.f 相当于 window.f=aaa.f 是吧,调用 window.f(),this 指向 window。问题是我的例子我把函数直接调用,和作为参数传出去再调用,我输出了 this 之后,发现函数作为参数传过去为什么 this 指向了 window,中间有涉及到 window 吗? |
16
whimsySun 2017-05-22 15:41:31 +08:00 1
@cheroky 不知道你之前是不是学过一些面向对象的语言,收到了影响。js 里面,你可以把函数当成一个单一个体,只是在调用的使用会有归属,不知道这个你能不能理解
|
17
Exin 2017-05-22 15:49:54 +08:00 via iPhone
建议楼主把 You dont know js 中的相关章节先仔细完整地阅读,讲的还是蛮清楚的
|
18
bramblex 2017-05-22 15:53:25 +08:00
@cheroky
const aaa = {f: function(){console.log(this)}} 下面两条有什么区别吗? xxx(aaa.f) === const f = aaa.f xxx(f) 如果你觉得上面两条没区别吗? f 只在调用的时候才会去找调用它的对象,传参的时候又没调用。 最后 f = aaa.f 和 window.f = aaa.f 有本质区别的。 |
19
Biwood 2017-05-22 15:54:02 +08:00 1
你这个问题问的挺好的,以后再项目中你会遇到很多次这种情况。
先说原因,obj2.getName(obj.getName) 等价于 obj2.getName(匿名函数),这个 obj.getName 引用的是一个匿名函数,传参的时候,匿名函数被赋值给了形参 f,这一步是关键,形参 f 默认没有绑定任何 Context,你觉得 f 的 Context 是 obj2 吗? f 不是 obj2 的属性,所以显然不是。对于没有手动绑定 Context 的函数,默认 Context 为全局对象,浏览器里面就是 window 对象,严格模式下面会是 undefined。 配合 ES5 里面的 Function.prototype.bind() 的用法,理解起来会容易许多。你可以在 Chrome 浏览器调试栏里面执行如下代码: var name = "global"; var obj = { name: "Yes", getName: function() { console.log(this.name); } } var obj2 = { name: "Yes2", getName: function(f) { console.dir(f); f(); } } obj2.getName(obj.getName.bind(obj2)) 对比一下跟你原来的写法有什么不同,同时看看打印出来的函数对象的具体结构,大概就能理解了 |
20
bramblex 2017-05-22 15:56:29 +08:00 1
@cheroky
楼主你的问题在于,你根本不理解在 js 函数和其他变量是一样的东西,一个函数里面的 this 是不会绑定一个特定的对象的,而是会在 [函数调用的那一刻] 寻找所调用它的对象。 所以你上面的例子,只有到 f() 这个执行,才会去找调用 f 的对象。但是现在没人在调用 f 啊,所以就默认是 window 或者 global |
21
bramblex 2017-05-22 16:00:13 +08:00
这个 this 叫做 “上下文指针”,指向的是这个函数在被调用的那一刻,直接调用这个函数的对象。
而函数在创建的时候,这个 this 是毫无意义的。 |
22
cheroky OP |
23
IdJoel 2017-05-22 17:17:22 +08:00
留一下 不忙了看 感谢 LZ 和大牛
|
24
crs0910 2017-05-22 22:54:14 +08:00 via iPhone
js 的 this 不是 self 而是 context
|
25
saga 2017-05-23 17:40:49 +08:00 1
|
26
wedaren 2017-05-26 16:10:56 +08:00 1
|