You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.02 06:46:04