Number() vs new Number()?

8
我试图理解使用m = Number()(导致typeof m评估为"number")与 m = new Number()(导致typeof m评估为"object")的区别。我本来期望无论哪种方式都是一个object,但当我在Number原型上添加了一个.helloWorld()方法后,我能够在使用任何一种实例化方法时访问它。
这里有什么不同?在编写Number()new Number()之间我做了什么不同的事情?为什么一个是number而另一个是object

这一系列文章中的图表为我澄清了JS对象模型:http://howtonode.org/object-graphs-2。 - Oliver Charlesworth
1
当Number作为函数而非构造函数被调用时,它执行类型转换。与之相反,当Number作为new表达式的一部分被调用时,它是一个构造函数:它初始化新创建的对象。 - Jonathan Lonowski
啊啊啊啊……JavaScript没有采用“一切皆为对象”的方法。注意了。 - temporary_user_name
@Aerovistae,恰恰相反,一切都是对象,但原始类型是为了方便而提供的。在有帮助的情况下,原始类型会被强制转换为对象:var x = 10; x.toString(16); /* A */ - RobG
因为很多人从未看过原始版本。 - temporary_user_name
显示剩余2条评论
2个回答

4
Number()单独返回一个数字原始值。当您调用new Number()时,将收到一个新的对象实例,该对象表示Number的(相关ES5规范)。

当您在原始值上调用属性时,该原始值会自动封装(就像Java中一样)为该对象的实例,这是让您可以在objectnumber上调用helloWorld()的原因。

然而,请尝试这样做;

var x = Number(5);
x.bar = function (x) { alert(x); };
x.bar("hello");

var y = new Number(5);
y.bar = function (x) { alert(x); };
y.bar("hello");

你会发现后者有效,而前者无效;在第一个例子中, number 被自动封装为数字,并且 bar 方法被添加到它(对象)上。当你调用 x.bar() 时,你创建了一个新的自动封装的数字,bar 不存在于其中。
在后者中,你向该数字实例添加了一个 bar 方法,它的行为类似于任何其他对象实例,因此它将在整个对象的生命周期内保留。

通常在全局/局部/参数名称中使用相同的名称是一个不好的想法;这样做会增加示例中的混淆。我建议您为匿名函数使用不同的参数名称而不是 x - vol7ron

3
这只是如何实现。此特定构造函数在未使用new时返回基本数字,而在使用new时返回对象包装数字。
您可以访问原型方法/属性以得到基元,因为在幕后,JavaScript将其转换为对象,调用原型方法,然后丢弃对象副本。这使您可以执行以下操作:
var myString = "foo";
console.log( myString.length ); //=> 3
console.log( typeof myString ); //=> "string"

第二行创建了一个原始类型的对象副本,检查该对象的长度属性,然后丢弃该对象副本。myString仍然保持为字符串原始类型。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接