我刚开始思考这个问题,但是在 jsFiddle 中试着操作时并没有发现任何不同之处。
var a = new Array(1),
b = Array(1);
console.log(a, b);
输出是两个数组,其中一个成员未定义。
使用for (in)
循环可以发现它们具有相同的属性。
这两者之间有什么区别?第一个是否只是显式地实例化对象?
请不要就使用数组字面量符号对我进行讲解,因为我已经知道这一点。我更希望填补上述知识空白。
我刚开始思考这个问题,但是在 jsFiddle 中试着操作时并没有发现任何不同之处。
var a = new Array(1),
b = Array(1);
console.log(a, b);
输出是两个数组,其中一个成员未定义。
使用for (in)
循环可以发现它们具有相同的属性。
这两者之间有什么区别?第一个是否只是显式地实例化对象?
请不要就使用数组字面量符号对我进行讲解,因为我已经知道这一点。我更希望填补上述知识空白。
使用 Array
,这两种方式是等效的。当作为函数调用时,new
会被自动注入:
15.4.1 作为函数调用的
Array
构造函数当
Array
被作为函数而非构造函数调用时,它会创建并初始化一个新的 Array 对象。因此函数调用Array(…)
等同于带有相同参数的对象创建表达式new Array(…)
。
摘自 ECMA-262 第三版(类似内容可见于 第五版)。也请参考 ECMA-262 ECMAScript 2020 规范(第十一版)中的 22.1.1 Array 构造函数。
Array()
构造函数时,没有使用new
运算符,它的行为与使用new
运算符时完全相同。”区别在于Array函数的实现方式。如果调用Array函数时没有使用new运算符,则返回一个Array实例的行为取决于具体的实现。例如,Mozilla的SpiderMonkey引擎会执行以下操作:
static JSBool
Array(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
{
jsuint length;
jsval *vector;
/* If called without new, replace obj with a new Array object. */
这是实际来源的实际评论。下面的代码行没有重现在这里。我想其他引擎也是这样做的。否则,行为未定义。关于这个话题的好读物是John Resig的帖子这里。
new
的Array
的行为在ECMA规范中有明确定义,正如其他答案所描述的那样。 - ZachBnew
创建一个新的对象(类实例),并将其作为 this
传递给构造函数。但是,一些函数会检测它们是否使用了 new
并且会像使用了 new
一样运行。其中之一是 Array
,因此没有任何区别。
如果您想自己创建这样的构造函数,可以像以下代码一样进行:
function Smth(val) {
if (!(this instanceof Smth)) {
return new Smth(val);
}
this.val = val;
}