【06】ES6: Array-Erweiterung

1. Erweiterungsoperator

Der Spread-Operator (Spread) besteht aus drei Punkten (…). Es handelt sich um die Umkehroperation des restlichen Parameters, bei der ein Array in eine durch Kommas getrennte Folge von Parametern umgewandelt wird.

1. Grundlegende Grammatik

[...array] // array表示要转换的数组

console.log(...[1, 2, 3]) // 1 2 3
console.log(1, ...[2, 3, 4], 5) // 1 2 3 4 5
[...document.querySelectorAll('div')] // [<div>, <div>, <div>]

2. Zweck

(1) Array kopieren

Arrays sind zusammengesetzte Datentypen. Wenn Sie sie direkt kopieren, kopieren Sie nur den Zeiger auf die zugrunde liegende Datenstruktur, anstatt ein völlig neues Array zu klonen.

// 存在问题:a2 并不是 a1 的克隆,而是指向同一份数据的另一个指针。修改 a2,会直接导致a1 的变化。
const a1 = [1, 2]
const a2 = a1
a2[0] = 2
a1 // [2, 2]

// ES5 中用变通方法复制数组(浅拷贝)
const a1 = [1, 2]
const a2 = a1.concat()

// 使用扩展运算符复制数组(浅拷贝)
const a1 = [1, 2]
const a2 = [...a1]

(2) Arrays zusammenführen

Das zusammengeführte Array ist nur eine flache Kopie, daher müssen Sie bei der Verwendung vorsichtig sein.

const arr1 = ['a', 'b']
const arr2 = ['c']
const arr3 = ['d', 'e']

// ES5 的合并数组
arr1.concat(arr2, arr3) // [ 'a', 'b', 'c', 'd', 'e' ]

// ES6 的合并数组
[...arr1, ...arr2, ...arr3] // [ 'a', 'b', 'c', 'd', 'e' ]

(3) Kombiniert mit Destrukturierungsauftrag

Der Spread-Operator kann mit einer Destrukturierungszuweisung kombiniert werden, um Arrays zu generieren.

const arr = [1, 2, 3]
// ES5
const first = arr[0], rest = arr.slice(1)
// ES6
const [first, ...rest] = arr

console.log(first) // 输出 1
console.log(rest) // 输出 [2, 3]

Wenn der Spread-Operator für die Array-Zuweisung verwendet wird, kann er nur an der letzten Position des Parameters platziert werden, andernfalls wird ein Fehler gemeldet.

const [...butLast, last] = [1, 2, 3, 4, 5] // 报错
const [first, ...middle, last] = [1, 2, 3, 4, 5] // 报错

(4) String in Array konvertieren

[...'hello'] // [ "h", "e", "l", "l", "o" ]
// ES6 之前字符串转数组是通过:'hello'.split('');

(5) Konvertieren Sie Array-ähnlich in Array

// arguments
function func() {
    
    
    console.log(arguments) // [Arguments] { '0': 1, '1': 2 }
    console.log([...arguments]) [ 1, 2 ]
}
func(1, 2)

// 任何定义了遍历器(Iterator)接口的对象。都可以用扩展运算符转为真正的数组。
let nodeList = document.querySelectorAll('div')
let array = [...nodeList]

(6) Array in Parameterarray konvertieren (Funktionsparameterübertragung)

Konvertieren Sie ein Array in eine durch Kommas getrennte Folge von Parametern, die einfach an eine Funktion übergeben werden können.

const arr = [1, 2, 3]

function sum(a, b, c) {
    
    
	return a + b + c
}

console.log(sum(...arr)) // 输出 6

2.Array.from()

Array-ähnliche Methoden können nicht direkt verwendet werden. Sie müssen das Array-ähnliche Array zuerst in ein Array konvertieren.

Die neue Methode Array.from() von ES6 Array, die zum Konvertieren von Array-ähnlichen Objekten (array-like) und durchlaufbaren Objekten (iterable) in echte Arrays zur Verwendung verwendet wird (einschließlich der neuen Datenstrukturen Set und Map von ES6).

Grundgrammatik

Array.from(arrayLike, mapFn, thisArg)
Parameter beschreiben
arrayLike Array-ähnliches Objekt oder iterierbares Objekt, das Sie in ein Array konvertieren möchten
mapFn Wenn dieser Parameter angegeben ist, führt jedes Element im neuen Array die Rückruffunktion aus
thisArg Optionaler Parameter, dieses Objekt beim Ausführen der Callback-Funktion mapFn

arrayLike

Jedes Objekt mit einer Längeneigenschaft kann über die Methode Array.from() in ein Array konvertiert werden.

const arrLike = {
    
    
  '0': 'a',
  '1': 'b',
  '2': 'c',
  length: 3
}

// ES5 的写法
var arr = [].slice.call(arrayLike) // ['a', 'b', 'c']
var arr = [].slice.apply(arrLike) // ['a', 'b', 'c']

// ES6 的写法
var arr = Array.from(arrLike)
// NodeList 对象
let ps = document.querySelectorAll('p')
Array.from(ps).filter(p => {
    
    
	return p.textContent.length > 100
})

// arguments 对象
function foo() {
    
    
	var args = Array.from(arguments)
	// ...
}
/* 部署了 Iterator 接口的数据结构 */
Array.from('hello') // ['h', 'e', 'l', 'l', 'o']

const namesSet = new Set(['a', 'b'])
Array.from(namesSet) // ['a', 'b']

const map = new Map([[1, 2], [2, 4], [4, 8]])
Array.from(map) // [[1, 2], [2, 4], [4, 8]]
// 数组对象,Array.from()会返回一个一模一样的新数组
Array.from([1, 2, 3]) // [1, 2, 3]
// 有 length 属性的对象
Array.from({
    
     length: 3 }) // [undefined, undefined, undefined]

mapFn-Rückruffunktion

Der zweite Parameter in Array.from ist eine Rückruffunktion ähnlich der Kartenfunktion. Die Rückruffunktion empfängt jedes Element im Array als eingehenden Parameter und verarbeitet dann den eingehenden Wert, um ein neues Array zu erhalten. . Array.from(obj, mapFn, thisArg) kann auch mit Map als Array.from(obj).map(mapFn, thisArg) umgeschrieben werden.

Array.from(arrayLike, x => x * x)
// 等同于
Array.from(arrayLike).map(x => x * x)

Array.from([1, 2, 3], x => x * x) // [1, 4, 9]
// 取出一组 DOM 节点的文本内容
let spans = document.querySelectorAll('span.name')

// map()
let names1 = Array.prototype.map.call(spans, s => s.textContent)

// Array.from()
let names2 = Array.from(spans, s => s.textContent)

thisArg

Der dritte Parameter in Array.from kann diesen Punkt in der Rückruffunktion binden. Dieser Parameter ist sehr nützlich. Wir können die verarbeiteten Daten vom Verarbeitungsobjekt trennen und verschiedene Datenverarbeitungsmethoden in kapseln. In verschiedenen Objekten verwendet die Verarbeitungsmethode der selbe Name.

Beim Aufrufen von Array.from zum Konvertieren des Datenobjekts können je nach tatsächlicher Situation unterschiedliche Verarbeitungsobjekte injiziert werden, um unterschiedliche Ergebnisse zu erzielen, was zur Entkopplung geeignet ist.

// 定义一个 obj 对象可以认作是,Array.from 回调函数中处理数据的方法集合,handle 是其中的一个方法,把 obj 作为第三个参数传给 Array.from 这样在回调函数中可以通过 this 来拿到 obj 对象。
let obj = {
    
    
  handle: function(n){
    
    
    return n + 2
  }
}

Array.from([1, 2, 3, 4, 5], function (x){
    
    
  return this.handle(x)
}, obj) // [3, 4, 5, 6, 7]

3. Array.of()

Die Methode Array.of() wird verwendet, um eine Reihe von Werten in ein Array umzuwandeln.

Array.of(3, 11, 8) // [3,11,8]
Array.of(3) // [3]
Array.of(3).length // 1

Der Hauptzweck dieser Methode besteht darin, die Mängel des Array-Konstruktors Array() auszugleichen. Da die Anzahl der Parameter unterschiedlich ist, ist das Verhalten von Array() unterschiedlich.

Array() // []
Array(3) // [, , ,] 参数只有一个正整数时,实际上是指定数组的长度
Array(3, 11, 8) // [3, 11, 8] 返回由参数组成的新数组

Im obigen Code gibt die Array()-Methode unterschiedliche Ergebnisse zurück, wenn sie keine Parameter, einen Parameter oder drei Parameter hat. Array() gibt nur dann ein neues Array bestehend aus Parametern zurück, wenn die Anzahl der Parameter mindestens 2 beträgt. Wenn der Parameter nur eine positive Ganzzahl hat, gibt er tatsächlich die Länge des Arrays an.

Array.of() kann grundsätzlich als Ersatz für Array() oder new Array() verwendet werden, und es gibt keine Überladungen aufgrund unterschiedlicher Parameter. Sein Verhalten ist sehr einheitlich.

Array.of() // []
Array.of(undefined) // [undefined]
Array.of(1) // [1]
Array.of(1, 2) // [1, 2]

Array.of() gibt immer ein Array von Argumentwerten zurück. Wenn keine Parameter vorhanden sind, wird ein leeres Array zurückgegeben.

Die Methode Array.of() kann mit dem folgenden Code simuliert werden.

function ArrayOf(){
    
    
	return [].slice.call(arguments)
}

4. Instanzmethoden

1、copyWithin()

Kopiert innerhalb des aktuellen Arrays die Mitglieder an der angegebenen Position an andere Positionen (die ursprünglichen Mitglieder werden überschrieben) und gibt dann das aktuelle Array zurück. Diese Methode ändert das ursprüngliche Array.

Array.prototype.copyWithin(target, start = 0, end = this.length)
Parameter beschreiben
Ziel Erforderliche Parameter. Beginnen Sie ab dieser Position mit dem Ersetzen der Daten. Wenn es ein negativer Wert ist, stellt er den Kehrwert dar
Start Optionale Parameter. Beginnen Sie mit dem Lesen der Daten ab dieser Position, die standardmäßig 0 ist. Wenn es sich um einen negativen Wert handelt, bedeutet dies, dass vom Ende an gezählt wird.
Ende Optionale Parameter. Stoppen Sie das Lesen von Daten an dieser Position, die standardmäßig der Array-Länge entspricht. Wenn es sich um einen negativen Wert handelt, bedeutet dies, dass vom Ende an gezählt wird.

Diese drei Parameter sollten alle numerische Werte sein. Andernfalls werden sie automatisch in numerische Werte umgewandelt.

// 将3号位直到数组结束的成员(4和5),复制到从0号位开始的位置,覆盖原来的1和2。
[1, 2, 3, 4, 5].copyWithin(0, 3) // [4, 5, 3, 4, 5]

// 将3号位复制到0号位
[1, 2, 3, 4, 5].copyWithin(0, 3, 4) // [4, 2, 3, 4, 5]

// -2相当于3号位,-1相当于4号位
[1, 2, 3, 4, 5].copyWithin(0, -2, -1) // [4, 2, 3, 4, 5]

2、find()、findIndex()、findLast()、findLastIndex()

Die Array-Abrufmethode ändert das ursprüngliche Array nicht.

Methode veranschaulichen
finden() Wird verwendet, um das erste Array-Mitglied zu finden, das die Kriterien erfüllt. Gibt das Mitglied zurück, wenn eines vorhanden ist, oder undefiniert, wenn kein Mitglied vorhanden ist, das die Kriterien erfüllt.
findIndex() Gibt die Position des ersten Array-Mitglieds zurück, das die Kriterien erfüllt, oder -1, wenn keines der Mitglieder die Kriterien erfüllt.
findLast() Wird verwendet, um das erste Array-Mitglied zu finden, das die Kriterien erfüllt. Gibt das Mitglied zurück, wenn eines vorhanden ist, oder undefiniert, wenn kein Mitglied vorhanden ist, das die Kriterien erfüllt. Beginnen Sie mit dem letzten Mitglied des Arrays und prüfen Sie vorwärts.
findLastIndex() Gibt die Position des ersten Array-Mitglieds zurück, das die Kriterien erfüllt, oder -1, wenn keines der Mitglieder die Kriterien erfüllt. Beginnen Sie mit dem letzten Mitglied des Arrays und prüfen Sie vorwärts.

Der erste Parameter ist eine Rückruffunktion, die von allen Array-Mitgliedern nacheinander ausgeführt wird.

Der zweite Parameter ist das Objekt, das zum Binden der Rückruffunktion verwendet wird.

[1, 4, -5, 10].find(n => n < 0) // -5

// 回调函数可以接受三个参数,依次为当前的值、当前的位置和原数组。
[1, 5, 10, 15].find(function(value, index, arr) {
    
    
	return value > 9
}) // 10

[1, 5, 10, 15].findIndex(function(value, index, arr) {
    
    
	return value > 9
}) // 2

// 绑定回调函数的this对象。
function f(v){
    
    
	return v > this.age
}
let person = {
    
    name: 'John', age: 20}
[10, 12, 26, 15].find(f, person) // 26
const array = [
	{
    
     value: 1 },
	{
    
     value: 2 },
	{
    
     value: 3 },
	{
    
     value: 4 }
]

array.findLast(n => n.value % 2 === 1) // { value: 3 }
array.findLastIndex(n => n.value % 2 === 1) // 2

Diese vier Methoden können alle NaN finden, was die Mängel der indexOf()-Methode des Arrays ausgleicht.

array.indexOf(item, start = 0) . Gibt die Position eines angegebenen Elements im Array zurück oder -1, wenn das angegebene Element nicht im Array gefunden wird.

[NaN].indexOf(NaN) // -1

// 借助 Object.is() 方法
[NaN].findIndex(y => Object.is(NaN, y)) // 0

3、filter()

Filtern Sie die Array-Mitglieder und geben Sie die Mitglieder, die die Bedingungen erfüllen, in ein neues Array zurück. Diese Methode verändert das ursprüngliche Array nicht.

Der erste Parameter ist eine Rückruffunktion. Alle Array-Mitglieder führen die Rückruffunktion nacheinander aus, und die Mitglieder, deren Rückgabeergebnis wahr ist, bilden ein neues Array und geben es zurück.

Der zweite Parameter ist das Objekt, das zum Binden der Rückruffunktion verwendet wird.

[1, 2, 3, 4, 5].filter(function (elem) {
    
    
	return (elem > 3)
}) // [4, 5]

[0, 1, 'a', false].filter(Boolean) // [1, 'a']
// 回调函数可以接受三个参数,依次为当前的值、当前的位置和原数组。
[1, 2, 3, 4, 5].filter(function (elem, index, arr) {
    
    
	return index % 2 === 0
}) // [1, 3, 5]

// 绑定回调函数内部的this变量。
const obj = {
    
     MAX: 3 }
const myFilter = function (item) {
    
    
	if (item > this.MAX) return true
}
[2, 8, 3, 4, 1, 3, 2, 9].filter(myFilter, obj) // [8, 4, 9]

4、map()

Übergeben Sie nacheinander alle Mitglieder des Arrays an die Parameterfunktion und geben Sie dann die Ergebnisse jeder Ausführung in ein neues Array zurück. Das ursprüngliche Array wird nicht verändert.

Der erste Parameter ist eine Rückruffunktion. Alle Array-Mitglieder führen die Rückruffunktion nacheinander aus, und die Ergebnisse bilden ein neues Array und werden zurückgegeben.

Der zweite Parameter ist das Objekt, das zum Binden der Rückruffunktion verwendet wird.

[1, 2, 3].map(function (n) {
    
    
	return n + 1
}) // [2, 3, 4]
// 回调函数可以接受三个参数,依次为当前的值、当前的位置和原数组。
[1, 2, 3].map(function(elem, index, arr) {
    
    
	return elem * index
}) // [0, 2, 6]


// 绑定回调函数内部的this变量。
const arr = ['a', 'b', 'c']
[1, 2].map(function (e) {
    
    
	return this[e]
}, arr) // ['b', 'c']

5、forEach()

Array-Schleife. Wird für jedes Element des Arrays aufgerufen und das Element an die Rückruffunktion übergeben. Es wird kein Ergebnis zurückgegeben, der Rückgabewert ist undefiniert. Durch das Ändern von Array-Elementen wird das ursprüngliche Array geändert.

Der erste Parameter ist eine Rückruffunktion, und alle Array-Mitglieder führen die Rückruffunktion nacheinander aus und durchlaufen sie in einer Schleife.

Der zweite Parameter ist das Objekt, das zum Binden der Rückruffunktion verwendet wird.

// 回调函数可以接受三个参数,依次为当前的值、当前的位置和原数组。
const arr = ['a', 'b', 'c']

arr.forEach(function(currentValue, index, arr) {
    
    
	console.log(currentValue)
})
// 'a' 0 ['a', 'b', 'c']
// 'b' 1 ['a', 'b', 'c']
// 'c' 2 ['a', 'b', 'c']

Schleife unterbrechen

(1) Verwenden Sie stattdessen eine for-Schleife oder eine for-in-Schleife. break beendet die gesamte Schleife, continue beendet diese Schleife.

let list = [1, 2, 3, 4]
for (let i = 0; i < list.length; i++) {
    
    
	if (i == 1) {
    
    
		continue // 退出本次循环
	}
	if (i == 2) {
    
    
		break // 结束整个循环
	}
}
// break 只会结束最里层的 for 循环,继续外面的 for 循环
for (var i = 1; i < 4; i++) {
    
    
	for(var j = 1; j < 6; j++) {
    
    
		console.log(i * j)
		if(j > 2) break
	}
} // 1 2 3 2 4 6 3 6 9
for 循环中 return 语句:跳出 for 循环,且不执行 for 循环之外的语句,直接跳出当前函数,返回 return 后的值。

因为 js 中 for 是没有局部作用域的概念的,所以只有把 for 循环放在函数中时,才可以在for循环中使用 return 语句。

(2) Return, Break und Continue können die forEach-Schleife nicht beenden. Die Rückkehr in forEach entspricht der Fortsetzung in der for-Schleife und kann diese Schleife verlassen.

// return 3 的元素跳过
var arr = [1, 2, 3, 4, 5]

arr.forEach(function (item) {
    
    
    if (item === 3) {
    
    
        return
    }
    console.log(item)
})
// 1
// 2
// 4
// 5

(3) Verwenden Sie try...catch, throw, um eine Ausnahme auszulösen und die forEach-Schleife zu beenden.

try {
    
    
	[1, 2, 3].forEach(item => {
    
    
		if (item === 2) throw('哈哈哈')
		console.log(item)
	})
} catch(e) {
    
    
	console.log(e, 'e')
}

// 1
// '哈哈哈' e

(4) Von einigen und allen umgesetzt. every beendet die Schleife, wenn es auf return false stößt. some beendet die Schleife, wenn sie auf „return true“ trifft.

// 使用 Array.some()
arr.some(item => {
    
    
	console.log(item) 
	return item === 2 // 当有数组有一项满足条件时结束并返回 true
})
 
// 使用 Array.ervey()
arr.every(item => {
    
    
	console.log(item)
	return item !== 2 // 检查数字中是否每一项都满足条件,如果有一项不满足就结束循环并返回 false
})

6、some()、every()

Diese beiden Methoden ähneln „assert“ und geben einen booleschen Wert zurück, um zu bestimmen, ob die Array-Mitglieder bestimmte Bedingungen erfüllen. Das ursprüngliche Array wird nicht verändert.

Der erste Parameter ist eine Rückruffunktion, die von allen Array-Mitgliedern nacheinander ausgeführt wird. Diese Funktion akzeptiert drei Parameter: das aktuelle Mitglied, die aktuelle Position und das gesamte Array und gibt dann einen booleschen Wert zurück.

Der zweite Parameter ist das Objekt, das zum Binden der Rückruffunktion verwendet wird.

[1, 2, 3, 4, 5].some(function (elem, index, arr) {
    
    
	return elem >= 3
}) // true

[1, 2, 3, 4, 5].every(function (elem, index, arr) {
    
    
	return elem >= 3
}) // false

arr.some() gibt „true“ zurück, solange ein Element die Bedingung erfüllt, andernfalls gibt es „false“ zurück; arr.every() gibt nur „true“ zurück, wenn alle Elemente die Bedingung erfüllen, andernfalls wird „false“ zurückgegeben.

7、reduce()

redu() akzeptiert eine Funktion als Akkumulator und reduziert das Array beginnend beim ersten Wert, bis der letzte Wert reduziert wird. Endlich als Wert berechnet. Das ursprüngliche Array wird nicht verändert.

Parameter veranschaulichen
(prev, cur, index, arr) => {} Erforderlich, Rückruffunktion.
prev: erforderlich. Der Anfangswert initialValue oder der Rückgabewert nach Abschluss der Berechnung.
cur: erforderlich. arr Das aktuell akkumulierte Element des Arrays.
Index: optional. Der Index des aktuell akkumulierten Elements.
arr: optional. Das nicht leere Array von arr, das akkumuliert werden soll.
Ursprünglicher Wert Optionaler Anfangswert. Wenn kein Anfangswert vorhanden ist, ist der von der Rückruffunktion zum ersten Mal akkumulierte prev das erste Element von arr, cur ist das zweite Element von arr und der Wert von index ist 1.
[1, 2, 3, 4, 5].reduce(function (a, b) {
    
    
	console.log(a, b) // 1 2 | 3 3 | 6 4 | 10 5 
	return a + b
}) // 15

[1, 2, 3, 4, 5].reduce(function (a, b) {
    
    
	return a + b
}, 10) // 25

8、fill()

arr.fill(value, start = 0, end = arr.length) füllt alle Elemente in einem Array vom Startindex bis zum Endindex mit einem festen Wert. Schließt den Abschlussindex aus. Startindex, Standardwert ist 0. Endindex, Standardwert ist this.length.

['a', 'b', 'c'].fill(7) // [7, 7, 7]

new Array(3).fill(7) // [7, 7, 7]

['a', 'b', 'c'].fill(7, 1, 2) // ['a', 7, 'c']

Beachten Sie, dass, wenn der ausgefüllte Typ ein Objekt ist, das zugewiesene Objekt dieselbe Speicheradresse hat und nicht das Deep-Copy-Objekt.

let arr = new Array(3).fill({
    
    name: 'Mike'})
arr[0].name = 'Ben'
arr // [{name: 'Ben'}, {name: 'Ben'}, {name: 'Ben'}]

let arr = new Array(3).fill([])
arr[0].push(5)
arr // [[5], [5], [5]]

9、Entries()、Keys() und Values()

Wird zum Durchlaufen des Arrays verwendet. Beide geben ein Traverser-Objekt zurück, das mit einer for...of-Schleife durchlaufen werden kann. Der einzige Unterschied besteht darin, dass „keys()“ Schlüsselnamen, „values()“ Schlüsselwerte und „entrys()“ Schlüssel-Wert-Paare durchläuft. Traverse .

for (let index of ['a', 'b'].keys()) {
    
    
	console.log(index)
}
// 0
// 1

for (let elem of ['a', 'b'].values()) {
    
    
  console.log(elem)
}
// 'a'
// 'b'

for (let [index, elem] of ['a', 'b'].entries()) {
    
    
  console.log(index, elem)
}
// 0 'a'
// 1 'b'

10、includes()

Die Array.prototype.includes-Methode gibt einen booleschen Wert zurück, der angibt, ob ein Array einen bestimmten Wert enthält, ähnlich wie die Includes-Methode der Zeichenfolge.

[1, 2, 3].includes(2)	// true
[1, 2, 3].includes(4) // false
[1, 2, NaN].includes(NaN) // true

Der zweite Parameter dieser Methode gibt die Startposition der Suche an, die standardmäßig 0 ist. Wenn der zweite Parameter eine negative Zahl ist, stellt er die reziproke Position dar. Wenn er größer als die Array-Länge ist (z. B. ist der zweite Parameter -4, aber die Array-Länge ist 3), wird er zurückgesetzt, um bei 0 zu beginnen .

[1, 2, 3].includes(3, 3) // false
[1, 2, 3].includes(3, -1) // true

Bevor es diese Methode gab, verwendeten wir normalerweise die indexOf-Methode des Arrays, um zu überprüfen, ob es einen bestimmten Wert enthält.

Die indexOf-Methode hat zwei Nachteile:

Erstens ist es nicht semantisch genug. Seine Bedeutung besteht darin, die erste Vorkommensposition des Parameterwerts zu finden. Daher muss verglichen werden, ob es nicht gleich -1 ist, was nicht intuitiv genug ist, um es auszudrücken.

Zweitens wird intern der strikte Gleichheitsoperator (===) zur Beurteilung verwendet, was zu einer Fehleinschätzung von NaN führen kann. Includes verwendet einen anderen Beurteilungsalgorithmus, daher gibt es kein solches Problem.

if (arr.indexOf(el) !== -1) {
    
    
	// ...
}

[NaN].indexOf(NaN) // -1
[NaN].includes(NaN) // true

11、flat()、flatMap()

Array.prototype.flat()

Wird verwendet, um verschachtelte Arrays in eindimensionale Arrays zu „flachen“. Diese Methode gibt ein neues Array zurück und verändert das ursprüngliche Array nicht.

flat() „glättet“ standardmäßig nur eine Ebene. Wenn Sie ein mehrschichtiges verschachteltes Array „flachen“ möchten, können Sie den Parameter der flat()-Methode als Ganzzahl schreiben und die Anzahl der gewünschten Ebenen angeben Flatten. Der Standardwert ist 1. Wenn der Parameterwert Infinity ist, wird er unabhängig von der Anzahl der Verschachtelungsebenen in ein eindimensionales Array konvertiert.

[1, 2, [3, 4]].flat() // [1, 2, 3, 4] 拉平一层

[1, 2, [3, [4, 5]]].flat() // [1, 2, 3, [4, 5]] 拉平一层

[1, 2, [3, [4, 5]]].flat(2) // [1, 2, 3, 4, 5] 拉平两层

[1, [2, [3]]].flat(Infinity) // [1, 2, 3] 全部拉平

[1, 2, , 4, 5].flat() // [1, 2, 4, 5] 跳过空位

Array.prototype.flatMap()

Führen Sie eine Funktion für jedes Mitglied des ursprünglichen Arrays aus (entspricht der Ausführung von Array.prototype.map() ) und führen Sie dann die Methode flat() für das Array der zurückgegebenen Werte aus. Diese Methode gibt ein neues Array zurück, ohne das ursprüngliche Array zu ändern.

flatMap() kann nur eine Array-Ebene erweitern.

Der erste Parameter ist eine Traversierungsfunktion, die drei Parameter akzeptieren kann, nämlich das aktuelle Array-Mitglied, die Position des aktuellen Array-Mitglieds (beginnend bei Null) und das ursprüngliche Array.

Der zweite Parameter wird verwendet, um dies in der Traversal-Funktion zu binden.

// 相当于 [[2, 4], [3, 6], [4, 8]].flat()
[2, 3, 4].flatMap((x) => [x, x * 2]) // [2, 4, 3, 6, 4, 8]

// 相当于 [[[2]], [[4]], [[6]], [[8]]].flat()
[1, 2, 3, 4].flatMap(x => [[x * 2]]) // [[2], [4], [6], [8]]

arr.flatMap(function callback(currentValue[, index[, array]]) {
    
    
	// ...
}[, thisArg])

12、at()

JavaScript unterstützt seit langem keine negative Indizierung von Arrays. Wenn Sie auf das letzte Mitglied eines Arrays verweisen möchten, können Sie arr[-1] nicht schreiben, sondern nur arr[arr.length - 1].

Dies liegt daran, dass der eckige Klammeroperator [] nicht nur für Arrays, sondern auch für Objekte in der JavaScript-Sprache verwendet wird. Bei Objekten steht der Schlüsselname in eckigen Klammern. Beispielsweise bezieht sich obj[1] auf den Schlüssel mit dem Schlüsselnamen string-1. Ebenso bezieht sich obj[-1] auf den Schlüssel mit dem Schlüsselnamen string-1. Da es sich bei JavaScript-Arrays um spezielle Objekte handelt, haben negative Zahlen in eckigen Klammern keine andere Semantik. Das heißt, es ist nicht möglich, eine neue Syntax zur Unterstützung negativer Indizes hinzuzufügen.

Um dieses Problem zu lösen, fügt ES2022 den Array-Instanzen die Methode at() hinzu, die eine Ganzzahl als Parameter akzeptiert, das Mitglied an der entsprechenden Position zurückgibt und eine negative Indizierung unterstützt. Diese Methode kann nicht nur für Arrays, sondern auch für Strings und typisierte Arrays (TypedArray) verwendet werden.

const arr = [5, 12, 8, 130, 44]
arr.at(2) // 8
arr.at(-2) // 130

// 如果参数位置超出了数组范围,at()返回undefined。
const sentence = 'This is a sample sentence';
sentence.at(0) // 'T'
sentence.at(-1) // 'e'
sentence.at(-100) // undefined
sentence.at(100) // undefined

13、toReversed()、toSorted()、toSpliced()、with()

Viele herkömmliche Array-Methoden ändern das ursprüngliche Array, z. B. push(), pop(), unshift(), shift() usw. Solange diese Methoden für das Array aufgerufen werden, ändert sich sein Wert. Es gibt jetzt einen Vorschlag, der es Operationen an Arrays ermöglicht, eine Kopie des ursprünglichen Arrays zurückzugeben, ohne es zu ändern.

Insgesamt gibt es vier solcher Methoden.

  • Array.prototype.toReversed() -> Array
  • Array.prototype.toSorted(compareFn) -> Array
  • Array.prototype.toSpliced(start, deleteCount, ...items) -> Array
  • Array.prototype.with(index, value) -> Array

Sie entsprechen jeweils den ursprünglichen Methoden des Arrays.

Die ursprünglichen Methoden, die diesen vier neuen Methoden entsprechen, haben genau die gleiche Bedeutung und Verwendung. Der einzige Unterschied besteht darin, dass das ursprüngliche Array nicht geändert wird, sondern nach der Operation eine Kopie des ursprünglichen Arrays zurückgegeben wird.

  • toReversed() 对应 reverse(),用来颠倒数组成员的位置。
  • toSorted() 对应 sort(),用来对数组成员排序。
  • toSpliced() 对应 splice(),用来在指定位置,删除指定数量的成员,并插入新成员。
  • with(index, value) 对应 splice(index, 1, value),用来将指定位置的成员替换为新的值。
const sequence = [1, 2, 3]
sequence.toReversed() // [3, 2, 1]
sequence // [1, 2, 3]

const outOfOrder = [3, 1, 2]
outOfOrder.toSorted() // [1, 2, 3]
outOfOrder // [3, 1, 2]

const array = [1, 2, 3, 4]
array.toSpliced(1, 2, 5, 6, 7) // [1, 5, 6, 7, 4]
array // [1, 2, 3, 4]

const correctionNeeded = [1, 1, 3]
correctionNeeded.with(1, 2) // [1, 2, 3]
correctionNeeded // [1, 1, 3]

14、isArray()

Bestimmen Sie das JS-Objekt. Wenn der Wert ein Array ist, ist er wahr, andernfalls ist er falsch.

Array.isArray(obj)
// 下面的函数调用都返回 true
Array.isArray([])
Array.isArray([10])
Array.isArray(new Array())
Array.isArray(new Array('a', 'b', 'c'))
// 鲜为人知的事实:其实 Array.prototype 也是一个数组。
Array.isArray(Array.prototype)

// 下面的函数调用都返回 false
Array.isArray()
Array.isArray({
    
    })
Array.isArray(null)
Array.isArray(undefined)
Array.isArray(17)
Array.isArray('Array')
Array.isArray(true)
Array.isArray(false)
Array.isArray(new Uint8Array(32))
Array.isArray({
    
     __proto__: Array.prototype })

So ermitteln Sie Arrays in ES5

(1) Art der Typerkennung

Es gibt kein Problem bei der Beurteilung von Basistypen, aber bei der Beurteilung eines Arrays wird ein Objekt zurückgegeben. (Zeichenfolge, Zahl, undefiniert, boolescher Wert, Symbol, Objekt, Funktion)

// 基本类型
typeof 123 // number
typeof '123' // string
typeof true // boolean

// 引用类型
typeof [1, 2, 3] // object

(2) Urteil der Instanz

Der Instanzoperator wird verwendet, um zu bestimmen, ob das aktuelle Objekt eine Instanz eines Konstruktors ist.

var arr = ['a', 'b', 'c']
console.log(arr instanceof Array) // true 
console.log(arr.constructor === Array) // true

Fügen Sie hier eine Bildbeschreibung ein
Die Prototypenkette der Array-Instanz zeigt auf die Eigenschaft Array.prototype. Der Operator „instanceof“ wird verwendet, um zu erkennen, ob die Eigenschaft Array.prototype in der Prototypenkette des Arrays vorhanden ist. Die Variable arr im obigen Code ist ein Array, und alles hat das Array.prototype-Eigenschaft. Der Rückgabewert ist true, was die Bestimmung des Array-Typs erleichtert.

Es ist jedoch zu beachten, dass das Prototypattribut geändert werden kann. Dies bedeutet also nicht unbedingt, dass es immer wahr ist, wenn es zunächst als wahr beurteilt wird.

(3) Beurteilung durch den Konstrukteur

Konstruktor ist ein Attribut für das Prototypobjekt des Konstruktors, das auf den aktuellen Konstruktor verweist.

Das Prototypobjekt auf dem von new erzeugten Instanzobjekt weist das Konstruktorattribut auf, das auf das Konstruktor-Array verweist, anhand dessen wir den Typ eines Arrays bestimmen können.

var arr = new Array('a', 'b', 'c')
arr.constructor === Array //true

Fügen Sie hier eine Bildbeschreibung ein
Der Konstruktor kann überschrieben werden, daher ist nicht garantiert, dass es sich um ein Array handelt. (Gemeinsame prototypische Vererbung)

var str = 'abc'
str.constructor = Array
str.constructor === Array // true

(4)Object.prototype.toString

Die toString-Methode des Objekts gibt [Objekttyp] zurück, wobei Typ der aktuelle Datentyp ist.

 Object.prototype.toString.call(arr) === '[object Array]'

5. Lücken im Array

Eine leere Position in einem Array bedeutet, dass an einer bestimmten Position des Arrays kein Wert vorhanden ist.

Die leere Position ist nicht undefiniert. Wenn der Wert einer bestimmten Position gleich undefiniert ist, hat sie immer noch einen Wert. Leere Positionen haben keinen Wert.

由于空位的处理规则非常不统一,所以建议避免出现空位。

forEach(), filter(), Reduce(), every() und some() überspringen alle Lücken.

map() überspringt Lücken, behält aber den Wert bei

join() und toString() behandeln Lücken als undefiniert, und undefiniert und null werden als leere Zeichenfolgen behandelt.

// forEach 方法
[, 'a'].forEach((x, i) => console.log(i)) // 1

// filter 方法
['a', , 'b'].filter(x => true) // ['a', 'b']

// every 方法
[, 'a'].every(x => x === 'a') // true

// reduce 方法
[1, , 2].reduce((x, y) => x + y) // 3

// some 方法
[, 'a'].some(x => x !== 'a') // false

// map 方法
[, 'a'].map(x => 1) // [, 1]

// join方法
[, 'a', undefined, null].join('#') // '#a##'

// toString 方法
[, 'a', undefined, null].toString() // ',a,,'

Die Methode Array.from() konvertiert die leeren Bits im Array in undefinierte Bits, das heißt, diese Methode ignoriert die leeren Bits nicht.

Array.from(['a', , 'b']) // ['a', undefined, 'b']

Der Spread-Operator (…) wandelt auch leere Bits in undefinierte um.

[...['a', , 'b']] // ['a', undefined, 'b']

copyWithin() kopiert die leeren Leerzeichen zusammen.

[, 'a', 'b', ,].copyWithin(2, 0) // [, 'a', , 'a']

fill() behandelt Lücken als normale Array-Positionen.

new Array(3).fill('a') // ['a', 'a', 'a']

Die for…of-Schleife durchläuft auch die Lücken.

let arr = [, ,]
for (let i of arr) {
    
    
	console.log(1)
}
// 1
// 1

Einträge(), Schlüssel(), Werte(), Find() und FindIndex() behandeln Lücken als undefiniert.

// entries()
[...[, 'a'].entries()] // [[0, undefined], [1, 'a']]

// keys()
[...[, 'a'].keys()] // [0, 1]

// values()
[...[, 'a'].values()] // [undefined, 'a']

// find()
[, 'a'].find(x => true) // undefined

// findIndex()
[, 'a'].findIndex(x => true) // 0

Ich denke du magst

Origin blog.csdn.net/weixin_45559449/article/details/134605069
Empfohlen
Rangfolge