为什么不使用Number作为构造函数?

时间:2008-12-15 18:09:26

标签: javascript oop constructor jslint

我在JSLint中输入了这个语句:

var number = new Number(3);

并收到以下消息:

  

不要使用Number作为构造函数。

为什么?该语句正在创建一个数字对象,而不是原始值,因此我不明白为什么使用new是一个问题。

编辑:感谢所有回复。他们让我进一步思考,所以我发布了一个后续问题here

6 个答案:

答案 0 :(得分:31)

除了断开===和typeof返回“object”之外,使用Number构造函数还会更改在布尔上下文中使用值的方式。由于“new Number(0)”是一个对象,而不是文字值,因此它的计算结果为“true”,因为它不是null。例如:

var n1 = 0;
var n2 = new Number(0);

n1 == n2  // true
n1 === n2 // false
if (n1) {
    // Doesn't execute
}
if (n2) {
    // Does execute, because n2 is an object that is not null
}

编辑:比在数字文字和数字对象之间断开===更糟糕,==甚至不能在两个数字对象之间工作(至少不是以直观的方式 - 他们测试身份,而不是平等)。

var n1 = new Number(3);
var n2 = new Number(3);

alert(n1 == n2); // false
alert(n1 === n2); // false

答案 1 :(得分:14)

var number = new Number(3);
alert(typeof number); // gives "object"

使变量number的类型Object可能不是最理想的结果。鉴于:

var number = Number(3);
alert(typeof number); // gives "number"

答案 2 :(得分:5)

new Number()不会返回与数字文字相同的对象。这意味着使用新的Number()break ===,这是在Javascript中检查完全相等的最佳方法。

>>> 3 == 1 + 2
true
>>> 3 === 1 + 2
true
>>> new Number(3) == 1 + 2
true
>>> new Number(3) === 1 + 2
false

您可以在附录C的作者书中JavaScript: The Good Parts找到JSLint行为的基本原理。

答案 3 :(得分:4)

不幸的是,JSLint docs没有进一步细节而不是“不期望看到”,所以我们只能猜测。我自己怀疑这是为了使类型检查更容易:

assert(typeof 3             === "number");
assert(typeof new Number(3) === "object");

如果在代码中混合使用两者,则类型检查会变得更复杂:

if (typeof foo === "number" || foo instanceof Number) { … }

但是,JSLint也会对Object和Array构造函数产生问题,而这些构造函数没有区别,所以它可能只是作者的编码风格偏好:

assert(typeof []           === "object");
assert(typeof new Array()  === "object");
assert(typeof {}           === "object");
assert(typeof new Object() === "object");

编辑:史蒂文的答案提出了一个很好的观点 - 非类型转换等式运算符(===)。此运算符永远不会将数字对象和数字基元视为相等,即使它们的值相同:

assert(3 !== new Number(3));

答案 4 :(得分:4)

速度较慢,需要更多内存。运行时可以将不可变文本视为不可变文本。这意味着当它在代码中的某个地方遇到3时,它可以将其优化为共享对象。使用Number构造函数时,将为每个实例分配新内存。

答案 5 :(得分:0)

  

在JavaScript中,Object类型不等于另一个Object类型,即使它们具有完全相同的值,除非它们都是EXACT SAME对象。

     

换句话说,在下面的Matthew示例中,n1 == n2是假的,因为您将两个REFERENCES与两个SEPARATE对象进行比较,但是n1 == n1为真,因为您正在比较对EXACT SAME对象的引用。

     

所以,虽然我现在明白为什么使用Number作为构造函数会导致问题,但我发现在比较Number对象时可以使用valueOf属性。

     

换句话说,n1.valueOf == n2.valueOf是真的! (这是因为你要比较valueOf FUNCTION的返回值,而不是对象本身的REFERENCES。)

这个答案/总结是从它不属于的问题中提取的。