即,以下代码如何:
var sup = new Array(5);
sup[0] = 'z3ero';
sup[1] = 'o3ne';
sup[4] = 'f3our';
document.write(sup.length + "<br />");
输出'5'作为长度,当你所做的就是设置各种元素?
我对此代码的“问题”是,如果不调用length
或getLength()
方法,我无法理解setLength()
的更改方式。当我执行以下任何操作时:
a.length
a['length']
a.length = 4
a['length'] = 5
在非数组对象上,它的行为类似于dict / associative数组。当我在数组对象上执行此操作时,它具有特殊含义。 JavaScript中的哪种机制允许这种情况发生? javascript是否有某种类型的属性系统翻译
a.length
a['length']
进入“get”方法和
a.length = 4
a['length'] = 5
进入“设定”方法?
答案 0 :(得分:13)
JavaScript中的所有内容都是一个对象。对于Array
,length
属性返回数组索引项的内部存储区大小。一些混淆可能会发挥作用,因为[]
运算符适用于数字和字符串参数。对于数组,如果将其与数字索引一起使用,则返回/设置预期的索引项。如果将它与字符串一起使用,它将返回/设置数组对象上的命名属性 - 除非字符串对应于数值,否则它将返回索引项。这是因为在JavaScript中,数组索引通过隐式toString()
调用强制转换为字符串。坦率地说,这只是让你头脑发热并说“JavaScript,这就是他们嘲笑你的原因”的其中一个。
浏览器之间的实际底层表示可能不同(或者可能不同)。除了使用它时提供的接口之外,我不会依赖任何其他东西。
您可以在MDN找到有关Javascript数组的更多信息。
答案 1 :(得分:2)
重要的是要知道当你执行sup['look'] = 4;
时,你没有使用关联数组,而是修改对象sup的属性。它等同于sup.look = 4;
,因为您可以随时在javascript对象上动态添加属性。 sup['length']
将在第一个示例中输出实例输出5。
答案 2 :(得分:2)
添加到tvanfosson的答案:在ECMA-262(3.0规范,我相信)中,数组被简单地定义为具有设置属性的这种行为(见15.4.5.1)。它没有一般的机制(至少截至目前) - 这就是它的定义方式,以及javascript解释器必须如何表现。
答案 3 :(得分:2)
这实际上取决于你打算用它做什么。
[].length
是“神奇的”
它实际上并不返回数组中的项数。它返回数组中最大的instated索引。
var testArr = []; testArr[5000] = "something"; testArr.length; // 5000
但是设定者背后的方法隐藏在引擎本身中 某些浏览器中的某些引擎会让您访问这些魔术方法的实现。 其他人会把一切都完全锁定。
所以不要依赖defineGetter和defineSetter方法,甚至是真的__proto__
方法,除非你知道哪些浏览器是你知道的目标,哪些不是你。
将来会有所改变,用ECMAScript Next / 6编写的选择加入应用程序可以访问更多。
符合ECMAScript 5标准的浏览器已经开始在对象中提供get
和set
魔法方法了,还有更多内容......但是在转发支持之前可能还需要一段时间对于oldIE和一吨智能手机等等......
答案 4 :(得分:1)
如果您打算实现具有类似阵列访问权限的对象,Array Mozilla dev center article是一个很好的资源。不幸的是,我不知道Array实现的深入细节,但该文章中有很多细节。
答案 5 :(得分:1)
Array
对象继承length
中的caller
,constructor
,Function.prototype
和name
属性。
答案 6 :(得分:0)
JavaScript数组就像任何其他对象一样是一个对象,但JavaScript为它提供了特殊的语法。
arr[5] = "yo"
以上是句法糖
arr.insert(5,"yo")
这是你如何将东西添加到常规对象。它是 insert 方法中改变arr.length
值的内容在此处查看我对customArray类型的实现:http://jsfiddle.net/vfm3vkxy/4/
答案 7 :(得分:0)
正如其他人提到的那样,JavaScript中的属性基本上可以充当数组(或字符串或其他输入)的获取器和设置器。
事实上,您可以自己尝试:
const test=[1,2,3,4,5]
test.length = 3
console.log(test) // [1,2,3]
test.length = 5
console.log(test) // guess what happens here!
据我所知,JS中的数组不能完全像关联数组那样工作,并且有一些元素放置在内存as contiguously as possible中(假设您可以有混合对象的数组),具体取决于JS引擎您正在考虑。
作为一个旁注,我最困惑的是,投票最多的答案一直散布着“一切都成为JavaScript对象”的过于简单的神话(或半真相)。 that is not exactly true,否则,例如,您将永远不会学习基元。
尝试执行以下操作:
const pippi = "pippi"
pippi.cat = "cat"
console.log(pippi.cat) // will it work? Throw an error? Guess why again
Spoiler:将字符串包装在第二行中用于该特定操作的一次性对象中,然后在下面的示例中,您将访问不存在的原语的属性(前提是您没有使用{ {1}}等),则得到String.prototype
。
答案 8 :(得分:0)
JavaScript数组的特征
在Javascript中,运行时很难知道数组是密集的还是稀疏的。因此,所有可以做的就是猜测。所有实现都使用启发式方法来确定数组是密集的还是稀疏的。例如,上面第2点中的代码可以向javascript运行时指示这很可能是稀疏数组的实现。如果使用初始计数初始化阵列,则可能表明这可能是密集阵列。
当运行时检测到数组为稀疏数组时,它的实现方式与对象相似。因此,建立了键/值映射而不是维护连续的数组。
更多参考- https://www.quora.com/How-are-javascript-arrays-implemented-internally