JavaScript数组长度修改的含义 [英] Javascript array length modification implications

查看:114
本文介绍了JavaScript数组长度修改的含义的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在尝试扩展 Array.prototype 时,我注意到了一些东西。我本质上是想写一个允许删除数组中最后一项的方法:

I noticed something while trying to extend Array.prototype. I essentially wanted to write a method which allows for the deletion of the last item in an array:

Array.prototype.removeLast = function() {
    delete this[this.length - 1];
};

这不会产生我期望的结果:

This doesn't produce the result I expected:

>>> var arr = [ 1, 2, 3 ];
[ 1, 2, 3 ]
>>> arr.removeLast();
undefined
>>> arr
[ 1, 2, undefined ]

所以我尝试了另一种方法:

So I tried another method:

Array.prototype.removeLast = function() {
    this.length--;
};

我得到了预期的结果。

>>> var arr = [ 1, 2, 3 ];
[ 1, 2, 3 ]
>>> arr.removeLast();
undefined
>>> arr
[ 1, 2 ]



问题



1)为什么数组索引删除不像对象键删除那样工作? (对于数组,引用似乎仍然存在,但只是引用 undefined 。对于对象,引用似乎已被完全删除。)

Questions

1) Why isn't array-index deletion operating like object-key deletion? (With arrays the reference still seems to exist, but just references undefined. With objects, the reference seems to be deleted entirely.)

2) this.length-方法安全吗?可能会导致内存泄漏,还是
更改对象的 length 属性还会导致运行检查并删除数组中所有被遗忘的索引吗?

2) Is the this.length-- method safe? Could it cause a memory leak, or does altering an object's length attribute also cause a check to run and delete any forgotten indices in the array?

3)前两个问题的答案是否会因实施情况而有所不同?

3) Do the answers to either of the previous 2 questions vary based on the implementation?

4)什么是好的实施方法? of removeLast

4) What's a good implementation of removeLast?

谢谢!

推荐答案

正如MDN为删除数组元素


删除数组元素时,数组长度不受影响。即使删除数组的最后一个元素,该设置仍然成立。

When you delete an array element, the array length is not affected. This holds even if you delete the last element of the array.

当delete运算符删除数组元素时,该元素不再位于数组中。在下面的示例中,trees [3]被删除。

When the delete operator removes an array element, that element is no longer in the array. In the following example, trees[3] is removed with delete.

对于您的数组,您尝试 delete 索引(及其值),该索引是使用 delete 运算符执行的,但未按照您的想法进行。索引/值已删除,但是JavaScript引擎如何组装数组并操纵其属性(例如 length )不会按照您的想法进行。它仍然会显示缺少的索引w / undefined ,这就是您所看到的。

For your Array, you are trying to delete an index (with it, its value), which is performed using the the delete operator, but not in the way you think. The index/value is removed, but how the JavaScript engine assembles the array and manipulates its properties (e.g., length) will not do what you think. It will still display the missing index w/ undefined, which is what you see.

为了更好地演示,如果 Object.keys(your_array),您会看到删除的数组索引没有存在;同样,如果执行 Object.values(your_array),则会看到未返回 undefined 的情况。出于所有目的和目的,您删除了该属性(索引)及其关联值。

To better demonstrate, if do Object.keys( your_array ) you will see that the index that you deleted of your array does not exist; likewise, if you perform Object.values( your_array ) you will see that the undefined is not returned. For all intents and purposes you deleted the property (the index) and its associated value.

您可以考虑使用 splice pop (如果有最后一个索引)来删除数组的最后一个元素;但是,这并不是没有意识到它们自己的作用:

You may consider using use splice, or pop (if last index), to remove the last element of the array; however, this isn't without recognizing their own effects:


  • 拼接将对数组重新排序,将值移动到新索引中;这与 delete 不同,后者将所有内容保持在其原始索引

  • splice will reorder the array, shifting the values into new indexes; this is different from delete, which keeps everything at its original index

pop 将仅删除数组中的最后一项/索引

pop will remove only the last item/index from the array

splice pop 都将更新数组的 length 属性

splice and pop will both update the length property of the array

console.log('\nDELETE');
var trees = ['redwood', 'bay', 'cedar', 'oak', 'maple'];
delete trees[3];
console.log('array: ', trees);
console.log('keys: ', Object.keys(trees) );
console.log('values: ', Object.values(trees) );
console.log('length: ', trees.length );
trees.forEach(val=>console.log(val)); // notice no undefined


console.log('\nPOP');
var trees = ['redwood', 'bay', 'cedar', 'oak', 'maple'];
trees.pop();
console.log('array: ', trees);
console.log('keys: ', Object.keys(trees) );
console.log('values: ', Object.values(trees) );
console.log('length: ', trees.length );
trees.forEach(val=>console.log(val));


console.log('\nSPLICE');
var trees = ['redwood', 'bay', 'cedar', 'oak', 'maple'];
trees.splice(3,1);
console.log('array: ', trees);
console.log('keys: ', Object.keys(trees) );
console.log('values: ', Object.values(trees) );
console.log('length: ', trees.length );
trees.forEach(val=>console.log(val));


1)为什么数组索引删除不像对象键删除那样工作? (对于数组,引用似乎仍然存在,但只是引用未定义。对于对象,引用似乎已被完全删除。)

1) Why isn't array-index deletion operating like object-key deletion? (With arrays the reference still seems to exist, but just references undefined. With objects, the reference seems to be deleted entirely.)


2)this.length--方法安全吗?它会导致内存泄漏,还是更改对象的length属性还会导致运行检查并删除数组中所有被遗忘的索引?

2) Is the this.length-- method safe? Could it cause a memory leak, or does altering an object's length attribute also cause a check to run and delete any forgotten indices in the array?



<最好不要自己操作和管理长度。从历史上看,不同的浏览器对 length 操作的反应不同。

我唯一见过 length 操作是清除数组(即 arr.length = 0 )。这比将其分配给新的空数组(即 arr = [] )更可取,因为该数组可能包含某些不应丢失或重建的属性。

The only time I've seen length manipulation used in recent years is to clear an array (i.e., arr.length = 0). This is preferred over assigning it to an new empty array (i.e., arr = []) for when the array may contain certain properties that should not be lost or re-constructed.


3)前两个问题之一的答案是否会因实现方式而有所不同?

3) Do the answers to either of the previous 2 questions vary based on the implementation?


4)removeLast的一个好的实现是什么?

4) What's a good implementation of removeLast?

arr.pop() arr.splice(-1, 1)

这篇关于JavaScript数组长度修改的含义的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆