怎么javascript阵列的实施?
-
21-08-2019 - |
题
即,如何下列代码:
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/联阵列。当我这样做的阵的目的,它具有特殊的意义。什么样的机构在JavaScript允许这样的事情发生?不javascript有某种类型的财产系统,这意味着
a.length
a['length']
入"获得"方法和
a.length = 4
a['length'] = 5
入"设定"的方法吗?
解决方案
在JavaScript一切都是对象。在一个Array
的情况下,length
属性返回该阵列的索引项目的内部存储区域的大小。一些混乱可能会发挥作用,该[]
操作适用于数字和字符串参数。对于数组,如果你有一个数字索引使用它,它会返回/套的预期索引项。如果你有一个字符串使用它,它会返回/设置阵列对象的命名属性 - 除非该字符串对应一个数值,然后返回索引项。这是因为在JavaScript数组索引通过隐式调用toString()
强制转换为字符串。坦率地说,这仅仅是一个更的那些事,让你从头开始你的头,说:“JavaScript的,这一点,这就是为什么他们嘲笑你。”
在实际的底层表示可以浏览器之间(也可以不或)不同。我不会依赖比与它一起工作时,提供的接口以外的任何其他。
您可以了解更多关于JavaScript数组在 MDN 。
其他提示
要添加到tvanfosson的回答是:在ECMA-262(3.0说明书中,我相信),阵列被简单地定义为具有这种行为设置属性(见15.4.5.1)。有没有通用的机制底层IT(至少目前) - 这是它只是如何定义的,以及JavaScript解释器应如何行为
这真的取决于你打算用它做什么。
[].length
是 “神奇”。结果,
它实际上并没有在数组中返回的项目数。它返回在数组中的最大instated索引。
var testArr = []; testArr[5000] = "something"; testArr.length; // 5000
但是,设定器后面的方法是隐藏在发动机本身。结果 在某些浏览器的一些引擎会给你访问他们的那些神奇的方法实现。 其他人将保持一切完全锁定。
所以不要依靠defineGetter和defineSetter方法,甚至,真的,__proto__
方法,除非你知道哪些浏览器,你知道你的目标,和你不是。
这将在未来,其中选择在应用写入的ECMAScript改变接下来/ 6将有权访问更多。
的ECMAScript 5兼容的浏览器已经开始提供get
和对象set
神奇的方法,有更多的惊喜......但它可能是一个消磨之前,你可以转储为过时的歌曲和智能手机的支持吨,等等...
要知道,当你做sup['look'] = 4;
不使用关联数组,而是修改对象的属性SUP是很重要的。它相当于sup.look = 4;
,因为你可以动态地随时添加于JavaScript对象的属性。 sup['length']
将在您的第一示例的实例输出5。
如果你打算实现与类似数组的访问对象中,阵列Mozilla的开发中心文章是一个很好的资源。不幸的是,我不知道在数组实现的深入细节,但该文章中有很多的细节。
Array
目继承 caller
, constructor
, length
, , name
属性 Function.prototype
.
一个JavaScript数组是一个对象,就像任何其他对象,但是JavaScript的赋予其特殊的语法。
arr[5] = "yo"
以上是的语法糖作为
arr.insert(5,"yo")
这是如何添加的东西到正规的对象。这里面是什么的的插入的方法改变arr.length的值
请参阅我实施CustomArray的类型在这里: http://jsfiddle.net/vfm3vkxy/4/一>
作为其他人提及的,在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数组不起作用酷似关联数组,你必须被放置在内存元素尽可能连续(考虑到可以有混合物体的阵列),这取决于JS引擎你正在考虑。
作为一个方面说明,我有点困惑,最投票的答案一直蔓延“一切是在JavaScript对象”的过于简单化的神话(或半真理); 这是不完全正确,否则你将永远学习的原语,例如。
尝试这样做:
const pippi = "pippi"
pippi.cat = "cat"
console.log(pippi.cat) // will it work? Throw an error? Guess why again
扰流:字符串被包裹在第二行上的特定动作的不重磨对象,然后在下面的一个你只是访问原始这是不存在的属性(提供没有用String.prototype
玩等),所以你得到undefined
。
Javascript 数组的特征
- 动态 - Javascript 中的数组可以动态增长 .push
- 可以是稀疏的 - 例如数组[50000] = 2;
- 可以很密集 - 例如数组 =[1, 2, 3, 4, 5]
在 Javascript 中,运行时很难知道数组是密集的还是稀疏的。所以它所能做的就是猜测。所有实现都使用启发式方法来确定数组是密集还是稀疏。例如,上面第 2 点中的代码可以向 javascript 运行时指示这可能是一个稀疏数组实现。如果数组使用初始计数进行初始化,则可能表明这可能是一个密集数组。
当运行时检测到数组是稀疏的时,它的实现方式与对象类似。因此,不是维护连续的数组,而是构建键/值映射。
更多参考-https://www.quora.com/How-are-javascript-arrays-implemented-internally