声明这样的数组之间的真正区别是什么:
var myArray = new Array();
和
var myArray = [];
nickf.. 922
存在差异,但该示例没有区别.
使用更详细的方法:参数new Array()
中有一个额外的选项:如果你将一个数字传递给构造函数,你将得到一个长度数组:
x = new Array(5); alert(x.length); // 5
为了说明创建数组的不同方法:
var a = [], // these are the same b = new Array(), // a and b are arrays with length 0 c = ['foo', 'bar'], // these are the same d = new Array('foo', 'bar'), // c and d are arrays with 2 strings // these are different: e = [3] // e.length == 1, e[0] == 3 f = new Array(3), // f.length == 3, f[0] == undefined ;
这有点不对劲.新的Array()和[]之间有一个非常重要的区别我将在我的回答中详细说明. (66认同)
但正如你的答案中所指出的那样,如果你完全疯了并且覆盖了数组函数,它就会有所不同. (29认同)
那么重要的是使用new运算符会导致解释器采取各种额外步骤转到全局作用域,查找构造函数,调用构造函数并分配结果......在大多数情况下将是一个运行时数组.只需使用[]就可以避免查找全局构造函数的开销.它可能看起来很小,但是当你在应用程序中拍摄近乎实时的性能时,它可能会有所作为. (18认同)
存在巨大的性能差异:http://jsperf.com/create-an-array-of-initial-size/2 (5认同)
没错,但在我添加它们的大多数地方你也不需要分号或换行符.这是关于一致性和易读性.你知道,恕我直言. (4认同)
@nickf你对`===`的使用可能会让外行人感到困惑 - 特别是那些测试会是假的_因为他们**不是**比较同一个对象_.它们可能是_indistinguishable_,但它们不是_equal_. (2认同)
coderjoe.. 770
使用隐式数组和数组构造函数创建数组之间的区别很微妙但很重要.
使用时创建数组
var a = [];
您告诉解释器创建一个新的运行时数组.根本不需要额外的处理.完成.
如果您使用:
var a = new Array();
你告诉解释器,我想调用构造函数" Array
"并生成一个对象.然后它通过执行上下文查找要查找的构造函数,并调用它,创建数组.
你可能会想"嗯,这根本不重要.它们是一样的!".不幸的是你无法保证.
请看以下示例:
function Array() { this.is = 'SPARTA'; } var a = new Array(); var b = []; alert(a.is); // => 'SPARTA' alert(b.is); // => undefined a.push('Woa'); // => TypeError: a.push is not a function b.push('Woa'); // => 1 (OK)
在上面的示例中,第一个呼叫将按照您的预期警告"SPARTA".第二个不会.你最终会看到未定义的.您还会注意到b包含所有本机Array对象函数,例如push
,另一个不包含.
虽然你可能希望这样的事情发生,它只是说明了一个事实[]
是不一样的new Array()
.
[]
如果你知道你只想要一个数组,那么最好只使用它.我也不建议四处走动并重新定义Array ...
存在差异,但该示例没有区别.
使用更详细的方法:参数new Array()
中有一个额外的选项:如果你将一个数字传递给构造函数,你将得到一个长度数组:
x = new Array(5); alert(x.length); // 5
为了说明创建数组的不同方法:
var a = [], // these are the same b = new Array(), // a and b are arrays with length 0 c = ['foo', 'bar'], // these are the same d = new Array('foo', 'bar'), // c and d are arrays with 2 strings // these are different: e = [3] // e.length == 1, e[0] == 3 f = new Array(3), // f.length == 3, f[0] == undefined ;
使用隐式数组和数组构造函数创建数组之间的区别很微妙但很重要.
使用时创建数组
var a = [];
您告诉解释器创建一个新的运行时数组.根本不需要额外的处理.完成.
如果您使用:
var a = new Array();
你告诉解释器,我想调用构造函数" Array
"并生成一个对象.然后它通过执行上下文查找要查找的构造函数,并调用它,创建数组.
你可能会想"嗯,这根本不重要.它们是一样的!".不幸的是你无法保证.
请看以下示例:
function Array() { this.is = 'SPARTA'; } var a = new Array(); var b = []; alert(a.is); // => 'SPARTA' alert(b.is); // => undefined a.push('Woa'); // => TypeError: a.push is not a function b.push('Woa'); // => 1 (OK)
在上面的示例中,第一个呼叫将按照您的预期警告"SPARTA".第二个不会.你最终会看到未定义的.您还会注意到b包含所有本机Array对象函数,例如push
,另一个不包含.
虽然你可能希望这样的事情发生,它只是说明了一个事实[]
是不一样的new Array()
.
[]
如果你知道你只想要一个数组,那么最好只使用它.我也不建议四处走动并重新定义Array ...
没有人提到,存在巨大差异.
你可能会认为new Array(2)
它与[undefined, undefined]
以前相同,因为我们有
new Array(2).length // 2 new Array(2)[0] === undefined // true new Array(2)[1] === undefined // true
但它不是!
我们来试试吧map()
:
[undefined, undefined].map(e => 1) // [1, 1] new Array(2).map(e => 1) // "(2) [undefined × 2]" in Chrome
看到?这不一样!但那是为什么呢?
根据ES6规范22.1.1.2,Array(len)
只创建一个length
设置为的新数组,仅此len
而已.因此,新数组中没有真正的元素.
虽然功能map()
,根据规范22.1.3.15首先检查HasProperty
然后调用回调,但事实证明:
new Array(2).hasOwnProperty(0) // false [undefined, undefined].hasOwnProperty(0) // true
这就是为什么你不能指望任何迭代函数像往常一样工作new Array(len)
.
BTW,Safari和Firefox对此有更好的表达:
// Safari new Array(2) // [](2) new Array(2).map(e => 1) // [](2) [undefined, undefined] // [undefined, undefined] (2) // Firefox new Array(2) // Array [ <2 empty slots> ] new Array(2).map(e => 1) // Array [ <2 empty slots> ] [undefined, undefined] // Array [ undefined, undefined ]
我已经向Chrome提交了一个问题,要求他们修复这个令人困惑的日志:https: //bugs.chromium.org/p/chromium/issues/detail?id = 732021
更新:它已经修好了.Chrome现在登录为
new Array(2) // (2) [empty × 2]
奇怪的是,new Array(size)
几乎[]
是Chrome中的2倍,在FF和IE中大致相同(通过创建和填充数组来衡量).只有了解阵列的大致尺寸才有意义.如果添加的项目数量超过了您提供的长度,则性能提升会丢失.
更准确:Array(
是一个快速恒定时间操作,不分配内存,wheras []
是一个设置类型和值的线性时间操作.
有关更多信息,以下页面介绍了您永远不需要使用的原因new Array()
您永远不需要
new Object()
在JavaScript中使用.请改用对象文字{}
.同样,不要使用new Array()
,[]
而是使用数组文字.JavaScript中的数组与Java中的数组完全不同,使用类似Java的语法会让您感到困惑.不要使用
new Number
,new String
或new Boolean
.这些表单会产生不必要的对象包装.只需使用简单的文字.
另请查看注释 - new Array(length)
表单没有任何用处(至少在今天的JavaScript实现中).
为了更好地理解[]
和new Array()
:
> [] [] > new Array() [] > [] == [] false > [] === [] false > new Array() == new Array() false > new Array() === new Array() false > typeof ([]) "object" > typeof (new Array()) "object" > [] === new Array() false > [] == new Array() false
以上结果来自Windows 7上的Google Chrome控制台.
第一个是默认对象构造函数调用.如果需要,您可以使用它的参数.
var array = new Array(5); //initialize with default length 5
第二个使您能够创建非空数组:
var array = [1, 2, 3]; // this array will contain numbers 1, 2, 3.
我可以从更具体的方式开始解释,这个例子基于Fredrik的好例子.
var test1 = []; test1.push("value"); test1.push("value2"); var test2 = new Array(); test2.push("value"); test2.push("value2"); alert(test1); alert(test2); alert(test1 == test2); alert(test1.value == test2.value);
我刚刚为数组添加了另一个值,并发出了四个警告:第一个和第二个是给我们存储在每个数组中的值,以确保值.他们将返回相同的!现在尝试第三个,它返回false,那是因为
JS将test1视为具有数据类型数组的VARIABLE,并将test2视为具有数组功能的OBJECT,这里几乎没有细微差别.
第一个区别是当我们调用test1时它不假思索地调用变量,它只返回存储在这个变量中的值而忽略它的数据类型!但是,当我们调用test2时,它调用Array()函数然后将它们的"Pushed"值存储在它的"Value"属性中,当我们警告test2时它也会发生同样的情况,它会返回数组对象的"Value"属性.
因此,当我们检查test1是否等于test2时,它们当然永远不会返回true,一个是函数,另一个是变量(带有一种数组),即使它们具有相同的值!
为了确保这一点,尝试第4个警报,并添加.value; 它会回归真实.在这种情况下,我们告诉JS"忽略容器的类型,无论是功能还是变量,请比较存储在每个容器中的值并告诉我们你看到了什么!" 这正是发生的事情.
我希望我能清楚地说出这个想法,对不起我的英语不好.