Javascript 如何实现“长度”

Javascript how `length` is implemented

本文关键字:长度 实现 何实现 Javascript      更新时间:2023-09-26

你知道在Javascript中,你可以使用length属性访问文本/数组的长度:

var obj = ["Robert", "Smith", "John", "Mary", "Susan"];
// obj.length returns 5;

我想知道这是如何实现的。Javascript 在调用时会计算长度属性吗?或者它只是一个静态属性,每当数组更改时都会更改。我的问题是由于javascript最佳实践中的以下混淆而提出的:

for(var i = 0; i < obj.length; i++)
{
}

我的问题:如果它是一个静态属性,那么在每次迭代中访问 length 属性就没什么可担心的,但如果它是在每次迭代时计算的,那么它会消耗一些内存。

我已经阅读了 ECMAScript 给出的以下定义,但它没有给出任何关于它是如何实现的线索。恐怕它可能会给出一个完整的数组实例,其中长度属性在运行时计算,如果结果是正确的,那么上述for()对内存是危险的,而是应该使用以下:

var count = obj.length;
for(var i = 0; i < count; i++)
{
}

JavaScript 中的数组不是真正的 Array 类型,而是真正的 Object 类型。

[].长度不是每次都重新计算,它是由++--运算符操作的。

请参阅下面的示例,其行为与array.length属性相同。

var ArrayLike = {
    length: 0,
    push: function(val){
        this[this.length] = val;
        this.length++;
    },
    pop: function(){
        delete this[this.length-1];
        this.length--;
    },
    display: function(){
        for(var i = 0; i < this.length; i++){
            console.log(this[i]);
        }
    }
}
// output
ArrayLike.length // length == 0
ArrayLike.push('value1') // length == 1
ArrayLike.push('value2') // length == 2
ArrayLike.push('value3') // length == 3
ArrayLike.pop() // length == 2
ArrayLike.length === 2 // true
var a = ["abc","def"];
a["pqr"] = "hello";

什么是长度?

2

为什么?

a.长度仅在数组的索引为数值时更新。当你写的时候

var a = ["abc","def"];

它在内部存储为:

a["0"] = "abc"
a["1"] = "def"

请注意,索引实际上是字符串的键。

再举几个例子:

1.)

var a = ["abc","def"];
a["1001"] = "hello";

什么是长度?

1002

2.) 好的,让我们再试一次:

var a = ["abc","def"];
a[1001] = "hello";

什么是长度?

1002

请注意,内部数组存储为

a["0"] = "abc"
a["1"] = "def"
a["1001"] = "hello"

3.)好的,最后一个:

var a = ["abc"];
a["0"] = "hello";

什么是 a[0]?

   "hello"

什么是长度?

1

很高兴知道 a.length 的实际含义:现在你知道了:a.length 比数组中存在的最后一个数字键多一个。

我想知道这是如何实现的。Javascript 在调用时会计算长度属性吗?或者它只是一个静态属性,每当数组更改时都会更改。

实际上,您的问题通常无法回答,因为所有ECMA规范都说:

此 Array 对象的 length 属性是一个数据属性,其 值在数值上始终大于每个可删除对象的名称 名称为数组索引的属性。

换句话说,规范定义了length属性的不变条件,但不是它的实现。这意味着不同的JavaScript引擎原则上可以实现不同的行为。