# [译] JavaScript 数组方法：变异 vs. 非变异

JavaScript 提供了许多方式去增加、删除和替换数组中的元素，有些会作用到原数组本身，有些则不是——它们会返回一个新数组。

1. `array.splice()`改变原始数组，而
2. `array.slice()`不会改变原始数组。

### 增加元素：变异方法

``````// since the array will be mutated,
// use 'let' rather than 'const'
let mutatingAdd = ['a', 'b', 'c', 'd', 'e'];

mutatingAdd.push('f'); // ['a', 'b', 'c', 'd', 'e', 'f']
mutatingAdd.unshift('z'); // ['z', 'a', 'b', 'c', 'd', 'e']
``````

• `array.push()` 增加一个元素到数组末尾
• `array.unshift()` 增加一个元素到数组开头

### 增加元素：非变异方法

``````// since we will not be mutating,
// use const
const arr1 = ['a', 'b', 'c', 'd', 'e'];

const arr2 = arr1.concat('f'); // ['a', 'b', 'c', 'd', 'e'. 'f']
console.log(arr1); // ['a', 'b', 'c', 'd', 'e']
``````

``````// since we will not be mutating,
// use const
const arr1 = ['a', 'b', 'c', 'd', 'e'];

const arr2 = [...arr1, 'f']; // ['a', 'b', 'c', 'd', 'e', 'f']
const arr3 = ['z', ...arr1]; // ['z', 'a', 'b', 'c', 'd', 'e']
``````

### 删除元素：变异方法

``````// since the array will be mutated,
// use 'let' rather than 'const'
let mutatingRemove = ['a', 'b', 'c', 'd', 'e'];
mutatingRemove.pop(); // ['a', 'b', 'c', 'd']
mutatingRemove.shift(); // ['b', 'c', 'd']
``````

• `array.pop()` 删除数组中的最末的元素
• `array.shift()` 删除数组中开头的元素

`array.pop()``array.shift()` 方法都返回被删除的元素。所以你可以抓取删除的元素并存到一个变量上。

``````let mutatingRemove = ['a', 'b', 'c', 'd', 'e'];

const returnedValue1 = mutatingRemove.pop();
console.log(mutatingRemove); // ['a', 'b', 'c', 'd']
console.log(returnedValue1); // 'e'

const returnedValue2 = mutatingRemove.shift();
console.log(mutatingRemove); // ['b', 'c', 'd']
console.log(returnedValue2); // 'a'
``````

``````let mutatingRemove = ['a', 'b', 'c', 'd', 'e'];
mutatingRemove.splice(0, 2); // ['c', 'd', 'e']
``````

1. 第一个参数是 `splice` 的起始索引位置。
2. 第二个参数是想要删除的数量。

``````let mutatingRemove = ['a', 'b', 'c', 'd', 'e'];
let returnedItems = mutatingRemove.splice(0, 2);
console.log(mutatingRemove); // ['c', 'd', 'e']
console.log(returnedItems) // ['a', 'b']
``````

### 删除元素：非变异方法

JavaScript 中的 `array.filter()` 方法会从原数组中创建一个新数组，但是这个新数组只包含符合特定要求的元素。

``````// since we will not be mutating,
// use const
const arr1 = ['a', 'b', 'c', 'd', 'e'];

const arr2 = arr1.filter(a => a !== 'e'); // ['a', 'b', 'd', 'f']
// OR
const arr2 = arr1.filter(a => {
return a !== 'e';
}); // ['a', 'b', 'd', 'f']
``````

*一些箭头函数的特性：

`array.slice()` 接受两个参数。

1. 第一个参数是开始拷贝的起始索引位置。
2. 第二个参数是拷贝结束的索引位置。结束位置的元素并不会包含进去（前开后闭）。
``````// since we will not be mutating,
// use const
const arr1 = ['a', 'b', 'c', 'd', 'e'];
const arr2 = arr1.slice(1, 5) // ['b', 'c', 'd', 'e']
const arr3 = arr1.slice(2) // ['c', 'd', 'e']
``````

### 替换元素：变异方法

1. 第一个参数是开始替换的索引位置。
2. 第二个参数是想要删除的元素个数。
3. 第三个之后的参数是想要插入到数组中的元素。
``````// since the array will be mutated,
// use 'let' rather than 'const'
let mutatingReplace = ['a', 'b', 'c', 'd', 'e'];
mutatingReplace.splice(2, 1, 30); // ['a', 'b', 30, 'd', 'e']
// OR
mutatingReplace.splice(2, 1, 30, 31); // ['a', 'b', 30, 31, 'd', 'e']
``````

### 替换元素：非变异方法

``````// since we will not be mutating,
// use const
const arr1 = ['a', 'b', 'c', 'd', 'e']
const arr2 = arr1.map(item => {
if(item === 'c') {
item = 'CAT';
}
return item;
}); // ['a', 'b', 'CAT', 'd', 'e']
``````

### 通过 `array.map()` 转换数据

`array.map()`是一个强大的方法，可以在不影响原始数据的前提下做数据转换。

``````// since we will not be mutating,
// use const
const origArr = ['a', 'b', 'c', 'd', 'e'];
const transformedArr = origArr.map(n => n + 'Hi!'); // ['aHi!', 'bHi!', 'cHi!', 'dHi!', 'eHi!']
// OR
const transformedArr = origArr.map(n => {
return n * 2;
})// ['aHi!', 'bHi!', 'cHi!', 'dHi!', 'eHi!']
console.log(origArr); // ['a', 'b', 'c', 'd', 'e']; // orignal array is intact
``````

-- EOF --
{"ft_lang_label":"__label__zh","ft_lang_prob":0.53780276,"math_prob":0.89602894,"size":4905,"snap":"2019-51-2020-05","text_gpt3_token_len":2512,"char_repetition_ratio":0.23444195,"word_repetition_ratio":0.2652106,"special_character_ratio":0.38960245,"punctuation_ratio":0.28280774,"nsfw_num_words":0,"has_unicode_error":false,"math_prob_llama3":0.9924518,"pos_list":[0],"im_url_duplicate_count":[null],"WARC_HEADER":"{\"WARC-Type\":\"response\",\"WARC-Date\":\"2020-01-28T19:27:37Z\",\"WARC-Record-ID\":\"<urn:uuid:fe2c2771-0773-4355-991b-53731729b56c>\",\"Content-Length\":\"41699\",\"Content-Type\":\"application/http; msgtype=response\",\"WARC-Warcinfo-ID\":\"<urn:uuid:493f40da-d624-4931-a7af-f6201c142951>\",\"WARC-Concurrent-To\":\"<urn:uuid:805774ff-6eb7-4231-958b-af69d5d064e9>\",\"WARC-IP-Address\":\"45.76.196.99\",\"WARC-Target-URI\":\"http://lightcss.com/javascript-array-methods-mutating-vs-non-mutating/\",\"WARC-Payload-Digest\":\"sha1:CLQUEF35RNSMDFF7KQEZZLQ6DMPMHEAS\",\"WARC-Block-Digest\":\"sha1:62RBCK3UDANAJ7WN53AKFBENNDXZQTBT\",\"WARC-Identified-Payload-Type\":\"text/html\",\"warc_filename\":\"/cc_download/warc_2020/CC-MAIN-2020-05/CC-MAIN-2020-05_segments_1579251783000.84_warc_CC-MAIN-20200128184745-20200128214745-00117.warc.gz\"}"}