为什么 js 对象里的方法不查找对象里的属性?

2017-06-20 10:54:29 +08:00
 rebeccaMyKid

对于作用域链的问题,这个代码我理解:

var name = 23;
function sayName(){
    return name;
}
console.log(sayName()); //23

当前函数作用域没有name就往上找。

但是,这个为什么不返回对象的 name 属性?

var name = 23;
var obj = {
    name: 666,
    getName: function(){
        return name;
    }
};
console.log(obj.getName()); //23

加上

return this.name; 就可以

1711 次点击
所在节点    问与答
13 条回复
jtsai
2017-06-20 11:06:48 +08:00
var name 是局部变量
name 是全局变量 (没有加 var )

这段代码,你在 obj 里定义的 name 跟 在 obj 外 定义的 name 都是 window.name
jtsai
2017-06-20 11:08:30 +08:00
噢 我搞错
mufeng
2017-06-20 11:09:48 +08:00
jtsai
2017-06-20 11:12:00 +08:00
name: 666, 不是定义变量 name,而是定义 obj 对象的属性 name 的值 = 666

getName: function(){ return name; } 这段是访问 name 这个变量,不是范围 obj.name 这个属性
acthtml
2017-06-20 11:13:49 +08:00
this 指向上级对象。
var 的作用域在 function 或全局中。
acthtml
2017-06-20 11:14:25 +08:00
@acthtml 应该这么说,this 指向运行时的上级对象。
morethansean
2017-06-20 11:16:39 +08:00
谁给你说你调一个对象下的函数对象的属性就会被自动加到 scope chain 里的……
DUSTINTHEWIND
2017-06-20 11:33:01 +08:00
我觉得应该是这样:这里面一共两个域:1. global 2. getName
getName 返回的 name 先在 getName 域里面查找,没找到,就到 global 域上找,找到了,于是打印 23
但是为什么不返回 obj 的 name,这.......总觉得哪里有点奇怪
forgcode
2017-06-20 12:02:15 +08:00
bj.getName()这个方法的执行环境在 window!
基本判断环境
1.是不是 new 的
2.是不是通过 call、apply
3.在其他上下文环境调用
4.然后就是默认,用严格模式就 undefined 不然就全局对象
noe132
2017-06-20 12:33:57 +08:00
因为 js 的对象是动态对象。如果 obj 本来没有 name 这个属性,你的 getname 依赖的是外部的变量 name 的值

若这个 obj 被其他地方修改,添加了个 name 属性,那么问题来了,要返回 obj.name 还是 obj 外部的变量 name 的值呢?

如果默认会返回 obj.name,那么就算 obj.name 没有定义,它的值也是 undefined,那到底是返回外部的值还是返回 undefined 呢?

所以 JS 中的作用域是在函数定义的时候确定的,不是函数调用的时候确定的。而且不像 Java,就算没有显示指定 this,作用域没找到相应变量时会自动找当前对象上的值,因为 Java 的对象都是固定写好的类,属性名和方法名都是写死的,不会出现上述问题。

况且,方法在对象上必须以 obj.method()的方式调用时 this 才指向 obj,如果 var method = obj.method; method(); method()中的 this 在非严格模式下是 global 对象,严格模式下是 undefined。
rebeccaMyKid
2017-06-20 14:34:55 +08:00
@morethansean 嗯!
vincedd
2017-06-21 07:46:39 +08:00
return this.name 等价于 return obj.name,调用问题中调用 getName 的时候,当前作用域是 getName,上一级的作用域应该是 window,这么理解对不对?
rebeccaMyKid
2017-06-21 07:56:56 +08:00
@vincedd 应该是这样的

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

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

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

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

© 2021 V2EX