new Number()和Number()的区别

75

new Number()Number()有什么区别?我知道new Number()创建了一个Number对象,而Number()只是一个函数,但在什么情况下应该调用哪个,为什么呢?

在相关说明上,Mozilla表示:

Do not use a Boolean object to convert a non-boolean value to a boolean value. Instead, use Boolean as a function to perform this task.

x = Boolean(expression);     // preferred
x = new Boolean(expression); // don't use

为什么会这样?我以为结果是一样的呢?

5个回答

73

Boolean(expression)会将表达式转换为一个布尔原始值,而new Boolean(expression)会在转换后的布尔值周围创建一个包装对象

通过以下示例可以看出它们之间的区别:

// Note I'm using strict-equals
new Boolean("true") === true; // false
Boolean("true") === true; // true

同时还有这个(感谢 @hobbs):

typeof new Boolean("true"); // "object"
typeof Boolean("true"); // "boolean"

注意: 尽管包装对象会在必要时自动转换为原始值(反之亦然),但我只能想到一种情况需要使用new Boolean或其他原始值的包装器——如果您想将属性附加到单个值。例如:

var b = new Boolean(true);
b.relatedMessage = "this should be true initially";
alert(b.relatedMessage); // will work

var b = true;
b.relatedMessage = "this should be true initially";
alert(b.relatedMessage); // undefined

4
typeof(Boolean("true")) === "boolean", 而 typeof(new Boolean("true")) === "object" - hobbs
10
“While the wrapper object will get converted to the primitive automatically when necessary”这句话是对的,但有点误导人。对象(包括Boolean对象)在布尔上下文中始终求值为trueif (new Boolean(0)) { alert("Oops, 0 is true."); }。要获取“预期”的值,请调用valueOfnew Boolean(0).valueOf() === false - Matthew Crumley
这个 JavaScript 库 https://github.com/lordnull/dice.js 会返回一个具有各种属性的 new Number(..),以及原始值。 - Erics

36
new Number( x )

创建一个新的包装对象。我认为没有任何有效的理由使用它。

Number( x )

将传递的参数转换为数字类型。您可以使用它将某些变量强制转换为数字类型。但是,以下方法同样可以完成这项工作:

+x

一般来说:

你不需要这些:

new Number()
new String()
new Boolean()
您可以使用这些来进行类型转换:
Number( value )
String( value )
Boolean( value )

然而,进行类型转换还有更简单的解决方案:

+x // cast to Number
'' + x // cast to String
!!x // cast to Boolean

33
你的速记可能更简单,但使用数字/字符串/布尔函数来完成相同的事情更清晰。 - Nigel
6
@Nigel 确实如此,但在 JavaScript 程序员中,将 + 作为强制转换为数字的前缀很常见且(据我所见)更受欢迎。 - Šime Vidas
6
日后维护你代码的人可能并不像你一样精通JS。我转做了一个JS项目,其中的“将字符串转为数字”的简写方式让我感到困惑。我花了几分钟时间才明白它的含义。在2019年,既然有更清晰易懂的替代方案,使用晦涩难懂的简写方式是没有必要的。 - Storm Muller
@StormMuller 几分钟?更像是几秒钟。更令人困惑的是 Number 以大写字母开头,而 JS 的命名约定是函数使用驼峰式大小写。更加令人困惑的是你可以使用 new 调用它,但也可以不用。这就是本问题的展示。 - Nearoo

20
始终值得参考规范,来自第15.7.1节:

Number作为函数而不是构造函数调用时,它执行类型转换。

同样地,使用Boolean作为函数(15.6.1):

Boolean作为函数而不是构造函数调用时,它执行类型转换。

这意味着您要查看第9.2节("ToBoolean"):

抽象操作ToBoolean根据表11将其参数转换为布尔类型的值:   
Undefined = false   
Null = false   
Boolean = 结果等于输入参数(没有转换)。   
Number = 如果参数是+0、-0或NaN,则结果为false;否则结果为true。   
String = 如果参数是空字符串(长度为零),则结果为false;否则结果为true。   
Object = true

new Boolean(value)Boolean(value)之间的区别基本上在于前者返回一个对象,而后者返回一个基元,根据上面的内容,这很重要,因为对象是真值。
var b = new Boolean(false);

display(b);            // Displays "false"
if (b) {
  display("true");     // This is the path that gets taken, displaying "true"
}
else {
  display("false");    // This path does NOT get taken
}

现场示例... 然而,对于测试的目的,您几乎总是需要布尔值。


1

使用 instanceof 的情况

const a = new Number('123'); // a === 123 is false
const b = Number('123'); // b === 123 is true
a instanceof Number; // is true
b instanceof Number; // is false

0
// Type conversion to primitive value    
const a = Number('42')
a === 42  // true
a.answer = 'You asked the wrong question'
a.answer // undefined

// Object
const b = new Number('42')
b === 42 // false
b.answer = 'Life, the Universe, and Everything'
b.valueOf() === 42 // true
b.answer // 'Life, the Universe, and Everything'

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