javascript - JS 数组上的对象属性有什么用?是否符合标准?

标签 javascript arrays javascript-objects

在 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 = [])。我不确定发生了什么,但我想因为数组是对象的子类型,所以它们的数组内容只是它们的属性之一? “利用”这种能力是一个好的做法吗?

最佳答案

虽然这可能*符合标准,但它不是最佳实践,如下例所示:

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 并将可枚举标志设置为 false。

您不想这样做的第二个原因是性能问题。当您开始向虚拟机分配任意属性时,虚拟机将以不同的方式对待您的数组。在 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

请记住,当您向对象分配属性时,对象的隐藏类会发生变化。它使虚拟机更难优化这些情况,并将单态调用站点转变为多态调用站点,导致去优化和其他严重破坏。

另请注意,每个数组都是一个对象;这并不奇怪。

[*] 我这么说只是可能是因为我缺少规范的链接,并且我不确定“use strict”是否也如此。例如,在严格模式下禁止向字符串添加随机属性。

关于javascript - JS 数组上的对象属性有什么用?是否符合标准?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32205310/

相关文章:

Javascript:类实例中的对象,从变量调用时重新分配值

javascript - Vue.js - vue-router 的基本 url 区分大小写吗?

javascript - Phantomjs - 使用 fs.write() 将数据写入新行不会转到下一行

arrays - Fortran 中零大小数组究竟发生了什么?

java - 为什么堆排序不被认为是一种稳定的排序算法

javascript - 迭代并比较两个对象数组的属性

JavaScript:如何使用正则表达式从字符串中删除空行?

javascript - 如何在 filepond 中添加下载图像或 Pdf/任何文档?

c++ - 如何使用索引初始化数组元素

JavaScript/设置从 0 开始递增索引