arrayIterators principle - garevna/js-course GitHub Wiki
Выведя в консоль свойство prototype конструктора массивов, можно убедиться, что эти структуры данных наследуют много методов, и некоторые из них мы уже знаем
▼ [constructor: ƒ, concat: ƒ, copyWithin: ƒ, fill: ƒ, find: ƒ, …]
► concat: ƒ concat()
► constructor: ƒ Array()
► copyWithin: ƒ copyWithin()
► entries: ƒ entries()
► every: ƒ every()
► fill: ƒ fill()
► filter: ƒ filter()
► find: ƒ find()
► findIndex: ƒ findIndex()
► flat: ƒ flat()
► flatMap: ƒ flatMap()
► forEach: ƒ forEach()
► includes: ƒ includes()
► indexOf: ƒ indexOf()
► join: ƒ join()
► keys: ƒ keys()
► lastIndexOf: ƒ lastIndexOf()
length: 0
► map: ƒ map()
► pop: ƒ pop()
► push: ƒ push()
► reduce: ƒ reduce()
► reduceRight: ƒ reduceRight()
► reverse: ƒ reverse()
► shift: ƒ shift()
► slice: ƒ slice()
► some: ƒ some()
► sort: ƒ sort()
► splice: ƒ splice()
► toLocaleString: ƒ toLocaleString()
► toString: ƒ toString()
► unshift: ƒ unshift()
► values: ƒ values()
► Symbol(Symbol.iterator): ƒ values()
► Symbol(Symbol.unscopables): {copyWithin: true, entries: true, fill: true, find: true, findIndex: true, …}
► __proto__: ObjectЧасть методов, с которыми мы уже знакомы, выполняют какую-то операцию с массивом ( добавляют элемент в массив, удаляют или заменяют элементы в массиве, объединяют несколько массивов в один и т.д. )
Итерирующие методы перебирают элементы массива один за другим строго в порядке возрастания их индексов ( за исключением reduceRight )
В процессе перебора значений происходит вызов указанной нами функции, которая и получает очередной элемент массива в качестве аргумента
| Обычные | Итерирующие |
|---|---|
concat |
entries |
copyWithin |
every |
fill |
filter |
flat |
find |
includes |
findIndex |
indexOf |
flatMap |
join |
forEach |
lastIndexOf |
keys |
pop |
map |
push |
reduce |
reverse |
reduceRight |
shift |
some |
slice |
sort |
splice |
values |
unshift |
Группа итерирующих методов массивов - пример реализации функциональной парадигмы в ООП
Точнее, mix двух парадигм программирования
Mix - потому что мы передаем этим методам в аргументах не только функцию, но и ссылку на объект
Обязательный первый аргумент, передаваемый методу в момент вызова - функция
function func ( arrayElement ) {
console.log ( arrayElement )
}
[ 7, "D", false ]
.forEach ( func )Обязательный формальный параметр функции ( func ) - текущее значение элемента массива ( arrayElement )
Функция ( назовем ее условно callback ) будет вызвана на каждой итерации ( для каждого элемента массива )
var arr = [ "google", "service", "user" ]
function test ( elem ) {
console.log ( elem )
}
Array.prototype.sampleMethod = function ( callback ) {
for ( var item of this )
callback ( item )
}
arr.sampleMethod ( test )Собственно, эти методы не изменяют исходный массив, поэтому алгоритм их работы скорее можно представить так:
var arr = [ "google", "service", "user", 0, false ]
function test ( elem ) {
return `${ typeof elem === "string" ? elem : "default" }`
}
Array.prototype.sampleMethod = function ( callback ) {
var res = []
for ( var item of this ) {
res.push ( callback ( item ) )
}
return res
}
arr.sampleMethod ( test )Функция, передаваемая методу, может иметь больше формальных параметров,
но остальные два являются опциональными ( необязательными )
var arr = [ "google", "service", "user" ]
function test ( elem, index ) {
return `${index}: ${elem}`
}
Array.prototype.sampleMethod = function ( callback ) {
var res = []
for ( var item of this )
res.push (
callback (
item,
this.indexOf ( item )
)
)
return res
}
console.log ( arr.sampleMethod ( test ) )var arr = [ "google", "service", "user", 0, false ]
function test ( elem, index, ref ) {
var tmp = typeof elem === "string" ?
ref.splice ( index, 1, true )[0] :
null
return ref [ index ]
}
Array.prototype.sampleMethod = function ( callback ) {
var res = []
for ( var item of this ) {
res.push (
callback (
item,
this.indexOf ( item ),
this
)
)
}
return res
}
arr.sampleMethod ( test )Функция, передаваемая методу в качестве первого аргумента, может быть анонимной, объявленной непосредственно в вызове метода
var numbers = [ 8, 4, 9, 7 ]
Array.prototype.sampleMethod = function ( callback ) {
var res = []
for ( var item of this ) {
res.push (
callback (
item,
this.indexOf ( item ),
this
)
)
}
return res
}
numbers.sampleMethod (
function ( item, index, arr ) {
console.log ( index, arr.indexOf( item ) === index )
console.log ( index, arr [ index ] === item )
}
)Кроме обязательного первого аргумента - ссылки на функцию
каждый метод имеет необязательный ( опциональный ) второй аргумент - ссылку на контекст вызова
( т.е. внутри метода this будет указывать на этот объект )
var numbers = [ 8, 4, 9, 7 ]
var alter = [ "google", 5, "figure", 11 ]
Array.prototype.sampleMethod = function ( callback, context ) {
var res = []
for ( var item of this ) {
res.push (
callback.call (
context,
item,
this.indexOf ( item ),
this
)
)
}
return res
}
var sample = numbers.sampleMethod (
function ( item, index, arr ) {
console.log ( this [ index ] )
console.log ( arr )
},
alter
)Итак, функция sample получает в переменной arr ссылку на исходный массив numbers, а this внутри функции sample указывает на массив alter