JavaScript对象初始化调用自身方法赋值报未定义错误解决
问题根因
你遇到的报错来自2个核心语法逻辑错误,另外代码里还有一个隐藏的this指向bug:
- 第一,对象字面量初始化是逐行解析属性的,当JS执行到
selling_price: get_selling_price(this.MRP, this.discount)这行时,整个Sock对象还没创建完成,前面定义的get_selling_price还没有挂载到对象上,JS会直接去全局作用域找名为get_selling_price的函数,全局没定义过这个函数,自然抛出未定义错误。 - 第二,对象字面量属性赋值位置的
this不指向当前正在创建的对象,而是指向外层全局作用域(浏览器环境是window,Node环境是globalThis),就算你解决了函数查找问题,这里的this.MRP、this.discount取到的都是undefined,算不出正确结果。 - 隐藏bug:
buy方法用了箭头函数,箭头函数不绑定自身this,会直接继承外层全局的this,调用时根本拿不到对象上的brand属性,会输出undefined。
修复后代码
最合理的写法是把selling_price改成getter访问器属性,同时把需要访问对象自身属性的方法从箭头函数改成普通函数,保证this指向正确:
let Sock = { brand: 'JS', color: 'Red', size: "extra-extra small", MRP: 1000, discount: 20, get_selling_price(MRP, discount) { return MRP - ((MRP * discount) / 100) }, // 访问时实时计算,后续修改MRP或折扣也能自动更新结果 get selling_price() { return this.get_selling_price(this.MRP, this.discount) }, buy() { console.log(`You are buying ${this.brand}`) }, sell() { console.log(`You are selling ${this.brand}`) }, } console.log(Sock.selling_price); // 输出800,符合预期 Sock.buy(); // 输出 You are buying JS Sock.sell(); // 输出 You are selling JS
如果你不需要动态更新售价,也可以在对象声明完成后再赋值selling_price,写法如下:
let Sock = { brand: 'JS', color: 'Red', size: "extra-extra small", MRP: 1000, discount: 20, get_selling_price(MRP, discount) { return MRP - ((MRP * discount) / 100) }, buy() { console.log(`You are buying ${this.brand}`) }, sell() { console.log(`You are selling ${this.brand}`) }, } // 对象创建完成后再调用方法赋值 Sock.selling_price = Sock.get_selling_price(Sock.MRP, Sock.discount); console.log(Sock.selling_price); // 同样输出800
这种写法的缺点是后续修改MRP或者discount时,selling_price不会自动同步更新,适合固定值场景。
内容的提问来源于stack exchange,提问作者Subhranil
相关产品推荐
相关产品推荐

