JS对象创建阶段内部调用属性为何首次返回undefined?
为什么对象创建阶段访问属性会得到undefined?
先把你的完整代码补全,方便大家理解场景:
var Pipe = { x: 100, p: function(){ console.log('p says x is ' + this.x); // 输出 p says x is undefined console.log('p says Pipe.x is ' + Pipe.x); // 输出 p says Pipe.x is undefined }(), // 这里是立即执行函数 y: function(){ console.log('y says x is ' + this.x); // 输出 y says x is 100 console.log('y says Pipe.x is ' + Pipe.x); // 输出 y says Pipe.x is 100 } }; Pipe.y();
核心原因:对象字面量的构建是顺序执行的
JavaScript在解析对象字面量的时候,是从左到右逐个处理键值对的:
- 当处理到
x:100时,这个属性会被添加到正在构建的临时对象里,但此时Pipe这个变量还没有完成赋值——它还没指向最终的完整对象。 - 接下来处理
p属性:我们定义了一个函数并立即执行它。这时候,Pipe变量还处于“未完全初始化”的状态,直接访问Pipe.x自然拿不到值,因为Pipe还没指向那个包含x:100的完整对象。 - 再说说
this.x:这个立即执行函数并不是通过Pipe.p()这种“对象方法调用”的方式执行的,而是直接被调用的,所以它的this绑定的是全局对象(浏览器里是window,Node.js里是global),全局对象里没有x属性,所以也是undefined。
等整个对象字面量解析完成后,Pipe变量才会完整指向这个包含x:100的对象。这时候调用Pipe.y(),y方法是通过对象调用的,this会绑定到Pipe,所以不管是this.x还是直接访问Pipe.x,都能拿到预期的100。
如果你想在创建阶段就访问x的值,可以试试这些方案
方案1:把x提取到外部变量
var xVal = 100; var Pipe = { x: xVal, p: function(){ console.log('p says x is ' + xVal); // 直接用外部变量,能拿到100 }(), y: function(){ console.log('y says x is ' + this.x); } };
方案2:使用构造函数
构造函数的执行逻辑是先创建实例,再给实例赋值属性,所以在构造函数内部的立即执行函数里,this能直接指向当前实例:
function Pipe() { this.x = 100; this.p = function() { console.log('p says x is ' + this.x); // 这里this是实例,输出100 }(); this.y = function() { console.log('y says x is ' + this.x); }; } var pipeInstance = new Pipe(); pipeInstance.y();
内容的提问来源于stack exchange,提问作者Suhail Gulzar
相关产品推荐
相关产品推荐

