数组中的任何更改是否会更改整个数组?

Does any change in an array gets to change the entire array?

我通过思考排序算法进入了这个问题。

在解释、编译或 运行 时间阶段更改数组内的元素位置是否与使用新元素重新创建整个数组相同?
它是否从一种语言彻底改变为另一种语言?
它是如何工作的?

想象一下JavaScript中的一个具体案例,例如:

let animals = ["monkey","zebra","banana","capybara"];

animals.splice(2,1); // returns ["banana"]

重写整个 animals 数组是否正确?还是有另一种类型的变化类型?在计算方面,这将如何改变工作?

Javascript 文档中指出,.splice() 方法“获取”一个数组对象,创建一个没有它的新数组,returns 另一个有它的数组作为输出,但是 它是如何工作的?

我是初学者,请耐心等待,如果可以的话,希望有好的阅读推荐,以进一步了解它。抱歉给您带来不便。

Does changing an element position inside an array would be the same, at the interpretation, compilation or run-time phases, to recreate the entire array with new elements?

我想你是在问这个:

Does changing an element position inside an array recreate the entire array with new elements?

  • 如果你使用数组索引器[],那么没有:数组没有重新创建,它是mutated in-place.
  • 如果使用Array.prototype.splice,那么no:数组没有重新创建,是mutated in-place .
    • 但是splice确实return一个包含删除元素的新数组。
  • 如果使用Array.prototype.filterand/orArray.prototype.map,则:只包含过滤元素的新数组是returned(并且原始输入数组根本没有修改:即没有任何变化)。
  • 如果您使用 Array.prototype.forEach 将元素分配回自身(无论如何您都不应该这样做),那么 :数组发生变异in-place.

Imagining a specific case in JavaScript, for example:

let animals = ["monkey","zebra","banana","capybara"];  
animals.splice(2,1); // returns ["banana"]

Would it be correct to state that the entire animals array was rewritten?

没有。那是不正确的。

正确的说法是“animals 数组发生了变异”。

It's stated in Javascript documentation that the .splice() method "takes" an array object, creates a new array without it and returns another one with it as an output, but how does it work?

我不知道您指的是什么“JavaScript 文档”,但这是不正确的。

JavaScript 文档的唯一权威来源是 the official ECMAScript specification 或 JavaScript 引擎供应商提供的文档(例如 Mozilla 的 Spidermonkey),记录在 MDN 上。

W3Schools等来源不权威。

...MDN 是这样说的 splice(强调我的):

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/splice

The splice() method changes the contents of an array by removing or replacing existing elements and/or adding new elements in place.


how does it work?

splice函数are defined in the ECMAScript specification (section 23.1.3.29)的inner-workings。

...可以概括为:

  1. 给定 splice 参数调用 ( this: Array, start: int, deleteCount: int );...
  2. 创建一个新数组来容纳 deleteCount 项:deletedItems
  3. this 中的元素从索引 start 复制到 start + deleteCountdeletedItems.
  4. this 中的元素从 start + deleteCount 复制到 this.length 向上 以填补删除项的空白。
  5. length 缩小为 this.length - deleteCount

在 TypeScript 中,像这样(忽略负参数的处理):

function splice<T>( this: T[], start: int, deleteCount: int ): T[] {
    
    const removedItems: T[] = [];
    const tailIdx = start + deleteCount;

    for( let i = start; i < tailIdx; i++ ) {
        removedItems.push( this[i] );
    }

    for( let i = tailIdx, f = start; i < this.length; i++, f++ ) {
        this[i] = this[f];
    }

    this.length = this.length - deleteCount;
}