在CMS代码中,我偶然发现了以下语句:
i18n = new Array();
i18n['PLUGIN_UPDATED'] = '<?php i18n("PLUGIN_UPDATED"); ?>';
i18n['ERROR'] = '<?php i18n("ERROR"); ?>';登录浏览器时:
i18n // []
i18n instanceof Array // true
i18n instanceof Object // true
i18n.length // 0
i18n.ERROR // 'Error string'这同样适用于对象文字构造(var myArr = [])。我不确定发生了什么,但我想是因为数组是对象的子类型,它们的数组内容只是它们的属性之一?“利用”这种能力是一种好的实践吗?
发布于 2015-08-25 21:35:16
虽然这可能是*标准编译器,但它不是最佳实践,如以下示例所示:
var x = [1, 2, 3]
x.foo = 'bar';
var y = [1, 2, 3]
function iter(arr) {
for(var x in arr) {
console.log(arr[x]);
}
}
iter(x); // 1, 2, 3, bar
iter(y); // 1, 2, 3这里更好的替代方法是使用Object.defineProperty,并将enumerable标志设置为false。
你不想这样做的第二个原因是性能。当您开始为数组分配任意属性时,VM将以不同的方式对待数组。在V8中,也可能发生以下情况:
var x = [1, 2, 3];
// x holds only small integers (smis) and the VM will
// use an optimized representation for your array with
// random access and nice cache locality
x['foo'] = 'bar';
// when assigning a random property to your array, v8
// will transform it from the fast smi array to
// a hash map, not treating it as an array anymore请记住,当您为对象分配属性时,对象的隐藏类也会发生变化。这使得VM更难优化这些情况,并将原本单一的调用点变成多态的,导致去优化和其他破坏。
还要注意的是,每个Array都是一个对象;这并不奇怪。
*我这么说可能只是因为我缺少规范的链接,而且我不确定"use strict“是否也是如此。例如,在严格模式下禁止向字符串添加随机属性。
https://stackoverflow.com/questions/32205310
复制相似问题