window.name = 'abc'; window.getName = function () { alert(name) } window.getName() // abc var obj = {} obj.name = '123' obj.getName = function () { alert(name) } obj.getName() // abc
怪吗?
![]() | 2 Fishdrowned 2017-06-21 08:57:32 +08:00 via Android 不怡啊,这根本不是作用域,少年你混淆概念了。 |
![]() | 3 Rice 2017-06-21 08:57:58 +08:00 这样你就觉得怪了? ``` window.name = 'abc'; var obj = {} obj.name = '123' obj.getName = function () { alert(this.name) } obj.getName() // 123 var a = obj.getName; a(); ``` 那这样呢? |
4 pandasjw 2017-06-21 08:58:54 +08:00 via Android 这是全局变量的问题吧。。。 |
![]() | 7 Rice 2017-06-21 09:10:56 +08:00 ![]() @jtsai #5 你这样想吧,js 不是现在这样设计 而是对象方法调用的时候,先查找有没有当前对象的 name 值,然后没有再向上查找,这样会发生什么后果。 这样的后果就是,如果这个对象一开始就没有 name 值,调用的时候就是全局变量 name 结果被人后来修改了,加上 name,调用就是对象的属性 name。 |
![]() | 8 R18 2017-06-21 09:16:12 +08:00 你的意思是 应该 alert 123 吗?但是你的 123 是赋值给了一个对象的属性 对象属性的调用是 obj.name 你直接使用 name 是会逐层寻找这个变量 最后就找到了全局中的 name |
![]() | 9 jin5354 2017-06-21 09:18:04 +08:00 在 ES6 前只有函数作用域和全局作用域,不要靠惯性和臆测写代码 |
10 morethansean 2017-06-21 09:19:53 +08:00 连续两天见到同一个问题了,到底是谁教你们的调对象下面的函数,对象的属性就会被自动加到 scope chain 里啊? |
![]() | 12 sliwey 2017-06-21 09:26:08 +08:00 不怪 |
![]() | 13 jtsai OP |
![]() | 15 luchenqun 2017-06-21 09:34:58 +08:00 http://t.cn/Ro5N24k 此问题到此终结! |
![]() | 19 BlackLynx 2017-06-21 10:07:48 +08:00 九楼十楼正解 |
![]() | 20 DUSTINTHEWIND 2017-06-21 10:52:53 +08:00 这个昨天一个帖子的问题一模一样 |
![]() | 21 xxfan 2017-06-21 11:27:43 +08:00 少年可以看高程 4.2 节来理解一下执行环境和作用域链. 我的理解是,作用域链,0 位是当前执行环境,也就是当前的 function(){} 花括号内的,显然 getName 这个函数内没有定义 name,找不到. 然后再后一位,就是 window 这个执行环境了,window 中可以找到 name.返回 abc. obj 并不是 getName 的执行环境,不在作用域链内,它只是"调用环境",也就是调用这个函数的对象而已.(所以 this 的话指向 obj,而作用域不包含它) |
![]() | 22 sunjourney 2017-06-21 13:54:47 +08:00 为什么怪,有什么其它语言 obj.getName() 会是 123 ?不是 123 我才要惊了 |
![]() | 23 jtsai OP @sunjourney 我感觉有点怪是因为 window instanceof Object // ture obj instanceof Object // ture window.toString === obj.toString // true 咋一看差不多的 |
![]() | 24 xiaojunjor 2017-06-21 14:56:53 +08:00 @luchenqun 哈哈哈哈哈哈,这个笑死我了 |
![]() | 25 Tokin 2017-06-22 09:59:44 +08:00 @sunjourney Javascript 中的任何一个全局函数或变量都是 window 的属性。 在 obj.getName 里调用的 name 是全局的 name 啊,如果要掉 obj 的 name 需要 this.name 或者 obj.name 不是吗?好奇。。。 式作用域的问题?调错了的可能性大吧。。。 |