为何JavaScript构造函数内调用方法正常,自执行函数(IIEF)形式调用却返回NaN?
为什么构造函数里的IIEF赋值会返回NaN?
这是个非常典型的this绑定场景问题,咱们拆开两个案例对比着看:
案例1为什么能正常工作?
先看案例1的核心代码:
this.disc = function () { return (this.carPrice > 20000 ? this.carPrice * .75 : this.carPrice < 5000 ? this.carPrice * .9 : this.carPrice * .85); }; this.discount = this.disc();
这里的this.disc()是作为当前Car实例的方法被调用的——你先把函数挂到了实例的disc属性上,然后通过实例去调用它。这种调用方式下,函数内部的this会自动绑定到当前的Car实例,自然能正确读取this.carPrice的值,计算出正常的折扣。
案例2为什么返回NaN?
再看案例2的关键代码:
this.discount = function () { return (this.carPrice > 20000 ? this.carPrice * .75 : this.carPrice < 5000 ? this.carPrice * .9 : this.carPrice * .85); }();
这里你把一个自执行函数(IIEF)的执行结果赋值给了this.discount,注意这个函数是被直接调用的(末尾的()),而不是作为实例的方法调用。根据JavaScript的this绑定规则:
- 在非严格模式下,直接调用普通函数时,
this会指向全局对象(浏览器里是window,Node.js里是global) - 在严格模式下,直接调用普通函数时,
this会是undefined
不管哪种情况,这个函数内部的this都不是当前的Car实例,所以this.carPrice就是undefined——用undefined参与数值计算,结果自然是NaN。
怎么解决?
如果你就是想在构造函数里直接计算出折扣值并存到this.discount,有几种简单的方案:
方案1:提前保存实例引用
把当前实例的this用变量存下来,在IIEF里用这个变量代替this:
function Car(plate, make, model, price, color) { this.carPrice = price; const self = this; // 保存当前实例的引用 this.discount = (function () { return (self.carPrice > 20000 ? self.carPrice * .75 : self.carPrice < 5000 ? self.carPrice * .9 : self.carPrice * .85); })(); }
方案2:用箭头函数的IIEF
箭头函数的this是词法绑定的,会继承外层作用域的this(也就是构造函数里的实例this):
function Car(plate, make, model, price, color) { this.carPrice = price; this.discount = (() => { return (this.carPrice > 20000 ? this.carPrice * .75 : this.carPrice < 5000 ? this.carPrice * .9 : this.carPrice * .85); })(); }
方案3:直接计算(最简洁)
其实如果只是单纯计算折扣值,完全没必要用函数包裹,直接写表达式就行:
function Car(plate, make, model, price, color) { this.carPrice = price; this.discount = this.carPrice > 20000 ? this.carPrice * .75 : this.carPrice < 5000 ? this.carPrice * .9 : this.carPrice * .85; }
内容的提问来源于stack exchange,提问作者Ark13th
相关产品推荐
相关产品推荐

