>  기사  >  웹 프론트엔드  >  흥미로운 JavaScript 기본 배열 함수를 자세히 설명하는 코드 예제

흥미로운 JavaScript 기본 배열 함수를 자세히 설명하는 코드 예제

黄舟
黄舟원래의
2017-03-06 14:37:591453검색

JavaScript에서는 Array 생성자를 사용하여 배열을 만들거나 배열 리터럴 []을 사용할 수 있습니다. 후자가 선호되는 방법입니다. Array 객체는 Object.prototype에서 상속되며, 배열에서 typeof 연산자를 실행하면 배열 대신 객체가 반환됩니다. 그러나 []instanceofArray도 true를 반환합니다. 즉, 문자열 객체, 인수 객체 등 배열과 유사한 객체의 구현은 더 복잡합니다. 인수 객체는 Array의 인스턴스는 아니지만 길이 속성을 가지며 인덱스를 통해 값을 얻을 수 있습니다. 배열처럼 반복됩니다.
이 기사에서는 배열 프로토타입 방법 중 일부를 검토하고 그 용도를 살펴보겠습니다.

  • 루프: .forEach

  • 판사: .some 및 .every

  • . Join 및 .concat

  • 스택 및 대기열 구현: .pop, .push, .shift 및 .unshift

  • 모델 매핑: . 맵

  • 쿼리: .filter

  • 정렬: .sort

  • 컴퓨팅: .reduce 및 .reduceRight

  • 복사: .slice

  • 강력한 .splice

  • 찾기: .indexOf

  • 연산자: in

  • approach.reverse

Loop:.forEach

이는 JavaScript에서 가장 간단한 방법이지만 IE7과 IE8에서는 이 방법을 지원하지 않습니다.

.forEach에는 콜백 함수가 배열을 탐색할 때 각 배열 요소에 대해 호출됩니다. 콜백 함수는

  • 값이라는 세 가지 매개 변수를 허용합니다. : 현재 요소

  • index: 현재 요소의 인덱스

  • array: 순회할 배열

추가로, 각 함수 호출의 컨텍스트(this)로 선택적 두 번째 매개변수를 전달할 수 있습니다.

['_', 't', 'a', 'n', 'i', 'f', ']'].forEach(function (value, index, array) {
    this.push(String.fromCharCode(value.charCodeAt() + index + 2))
}, out = [])
out.join('')
// <- &#39;awesome&#39;

.join은 나중에 언급될 것입니다. 이 예에서는 서로 다른 값을 연결하는 데 사용됩니다. ​​배열 요소에서 효과는 out[0] + ” + out[1] + ” + out[2] + ” + out[n]과 유사합니다.

.forEach 루프는 사용할 수 없습니다. 옵션을 발생시키는 것은 현명하지 않습니다. 다행스럽게도 작업을 중단하는 다른 방법이 있습니다: .some 및 .every

.NET에서 열거형을 사용한 경우 이 두 가지 방법은 동일합니다. .Any(x => 이며 선택적 두 번째 컨텍스트 매개변수도 있습니다. MDN은 .some을 다음과 같이 설명합니다.


some은 콜백 함수가 호출될 때까지 배열의 각 요소에 대해 콜백 함수를 실행합니다. . 대상 요소가 발견되면 일부는 즉시 true를 반환하고, 그렇지 않으면 일부는 지정된 값을 가진 배열 인덱스에 대해서만 실행됩니다.

콜백 함수의 값이

이 아닌 false를 반환합니다. .join과 .concat

.join과 .concat은 종종 혼동됩니다. .join(separator)은 구분 기호를 사용하여 배열 요소를 결합하고 구분 기호가 제공되지 않으면 문자열 형식을 반환합니다. 기본 .concat이 소스 배열의 얕은 복사본으로 사용됩니다. concat의 일반적인 사용법: array.concat(val, val2, val3, valn)

<.>.concat은 새 배열을 반환합니다.

    array.concat()는 인수 없이 소스 배열의 얕은 복사본을 반환합니다. >얕은 복사본은 새 배열과 원본 배열이 유지됨을 의미합니다. 동일한 객체 참조는 일반적으로 좋은 것입니다. 예:
  • max = -Infinity
    satisfied = [10, 12, 10, 8, 5, 23].some(function (value, index, array) {
        if (value > max) max = value
        return value < 10
    })
    console.log(max)
    // <- 12
    satisfied
    // <- true

    스택 및 큐 구현: .pop, .push, .shift 및 .unshift

  • .push가 배열 끝에 요소를 추가할 수 있다는 것은 누구나 알고 있지만 [].push('a', 'b', 'c', 'd', 'z')를 사용하면 한 번에 여러 요소를 추가할 수 있다는 것을 알고 계십니까?
  • .pop 메소드는 .push의 반대 작업으로, 삭제된 배열의 마지막 요소를 반환합니다. 배열이 비어 있으면 void 0(정의되지 않음)이 반환됩니다. .pop 및 .push를 사용하여 LIFO(후입 선출) 스택을 만듭니다.

    var a = { foo: &#39;bar&#39; }
    var b = [1, 2, 3, a]
    var c = b.concat()
    console.log(b === c)
    // <- false
    b[3] === a && c[3] === a
    // <- true
  • 모델 매핑: .map
  • .map은 배열의 각 요소에 대한 콜백 메서드를 제공하고 호출 결과로 구성된 새 배열을 반환합니다. 콜백 함수는 값이 할당된 배열 인덱스에 대해서만 실행됩니다. 삭제되거나 할당되지 않은 요소에 대해서는 호출되지 않습니다.

Array.prototype.map은 위에서 언급한 .forEach, .some 및 .every와 동일한 매개변수 형식을 갖습니다. .map(fn(value, index, array), thisArgument)

function Stack () {
    this._stack = []
}
Stack.prototype.next = function () {
    return this._stack.pop()
}
Stack.prototype.add = function () {
    return this._stack.push.apply(this._stack, arguments)
}
stack = new Stack()
stack.add(1,2,3)
stack.next()
// <- 3
相反,可以使用.shift和 .unshift创建FIFO (first in first out)队列。

function Queue () {
    this._queue = []
}
Queue.prototype.next = function () {
    return this._queue.shift()
}
Queue.prototype.add = function () {
    return this._queue.unshift.apply(this._queue, arguments)
}
queue = new Queue()
queue.add(1,2,3)
queue.next()
// <- 1
Using .shift (or .pop) is an easy way to loop through a set of array elements, while draining the array in the process.
list = [1,2,3,4,5,6,7,8,9,10]
while (item = list.shift()) {
    console.log(item)
}
list
// <- []

undefine × 3은 삭제되거나 지정되지 않은 요소에 대해 .map이 호출되지 않지만 결과 배열에는 여전히 포함된다는 점을 잘 설명합니다. .map은 배열을 생성하거나 변경할 때 매우 유용합니다. 다음 예를 참조하세요.

values = [void 0, null, false, &#39;&#39;]
values[7] = void 0
result = values.map(function(value, index, array){
    console.log(value)
    return value
})
// <- [undefined, null, false, &#39;&#39;, undefined × 3, undefined]

쿼리: .filter

filter는 각 배열 요소에 대해 콜백 함수를 한 번씩 실행하고 A를 반환합니다. 콜백 함수가 true를 반환하는 요소로 구성된 새 배열입니다. 콜백 함수는 지정된 값이 있는 배열 항목에 대해서만 호출됩니다.

通常用法:.filter(fn(value, index, array), thisArgument),跟C#中的LINQ表达式和SQL中的where语句类似,.filter只返回在回调函数中返回true值的元素。

[void 0, null, false, &#39;&#39;, 1].filter(function (value) {
    return value
})
// <- [1]
[void 0, null, false, &#39;&#39;, 1].filter(function (value) {
    return !value
})
// <- [void 0, null, false, &#39;&#39;]

排序:.sort(compareFunction)

如果没有提供compareFunction,元素会被转换成字符串并按照字典排序。例如,”80″排在”9″之前,而不是在其后。

跟大多数排序函数类似,Array.prototype.sort(fn(a,b))需要一个包含两个测试参数的回调函数,其返回值如下:

  • a在b之前则返回值小于0

  • a和b相等则返回值是0

  • a在b之后则返回值小于0

[9,80,3,10,5,6].sort()
// <- [10, 3, 5, 6, 80, 9]
[9,80,3,10,5,6].sort(function (a, b) {
    return a - b
})
// <- [3, 5, 6, 9, 10, 80]

计算:.reduce和.reduceRight

这两个函数比较难理解,.reduce会从左往右遍历数组,而.reduceRight则从右往左遍历数组,二者典型用法:.reduce(callback(previousValue,currentValue, index, array), initialValue)。

previousValue 是最后一次调用回调函数的返回值,initialValue则是其初始值,currentValue是当前元素值,index是当前元素索引,array是调用.reduce的数组。

一个典型的用例,使用.reduce的求和函数。

Array.prototype.sum = function () {
    return this.reduce(function (partial, value) {
        return partial + value
    }, 0)
};
[3,4,5,6,10].sum()
// <- 28

如果想把数组拼接成一个字符串,可以用.join实现。然而,若数组值是对象,.join就不会按照我们的期望返回值了,除非对象有合理的valueOf或toString方法,在这种情况下,可以用.reduce实现:

function concat (input) {
    return input.reduce(function (partial, value) {
        if (partial) {
            partial += &#39;, &#39;
        }
        return partial + value
    }, &#39;&#39;)
}
concat([
    { name: &#39;George&#39; },
    { name: &#39;Sam&#39; },
    { name: &#39;Pear&#39; }
])
// <- &#39;George, Sam, Pear&#39;

复制:.slice

和.concat类似,调用没有参数的.slice()方法会返回源数组的一个浅拷贝。.slice有两个参数:一个是开始位置和一个结束位置。
Array.prototype.slice 能被用来将类数组对象转换为真正的数组。

Array.prototype.slice.call({ 0: &#39;a&#39;, 1: &#39;b&#39;, length: 2 })
// <- [&#39;a&#39;, &#39;b&#39;]
这对.concat不适用,因为它会用数组包裹类数组对象。

Array.prototype.concat.call({ 0: &#39;a&#39;, 1: &#39;b&#39;, length: 2 })
// <- [{ 0: &#39;a&#39;, 1: &#39;b&#39;, length: 2 }]

此外,.slice的另一个通常用法是从一个参数列表中删除一些元素,这可以将类数组对象转换为真正的数组。

function format (text, bold) {
    if (bold) {
        text = &#39;<b>&#39; + text + &#39;</b>&#39;
    }
    var values = Array.prototype.slice.call(arguments, 2)
    values.forEach(function (value) {
        text = text.replace(&#39;%s&#39;, value)
    })
    return text
}
format(&#39;some%sthing%s %s&#39;, true, &#39;some&#39;, &#39;other&#39;, &#39;things&#39;)

强大的.splice

.splice 是我最喜欢的原生数组函数,只需要调用一次,就允许你删除元素、插入新的元素,并能同时进行删除、插入操作。需要注意的是,不同于`.concat和.slice,这个函数会改变源数组。

var source = [1,2,3,8,8,8,8,8,9,10,11,12,13]
var spliced = source.splice(3, 4, 4, 5, 6, 7)
console.log(source)
// <- [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12 ,13]
spliced
// <- [8, 8, 8, 8]

正如你看到的,.splice会返回删除的元素。如果你想遍历已经删除的数组时,这会非常方便。

var source = [1,2,3,8,8,8,8,8,9,10,11,12,13]
var spliced = source.splice(9)
spliced.forEach(function (value) {
    console.log(&#39;removed&#39;, value)
})
// <- removed 10
// <- removed 11
// <- removed 12
// <- removed 13
console.log(source)
// <- [1, 2, 3, 8, 8, 8, 8, 8, 9]

查找:.indexOf

利用.indexOf 可以在数组中查找一个元素的位置,没有匹配元素则返回-1。我经常使用.indexOf的情况是当我有比较时,例如:a === ‘a’ || a === ‘b’ || a === ‘c’,或者只有两个比较,此时,可以使用.indexOf:['a', 'b', 'c'].indexOf(a) !== -1。

注意,如果提供的引用相同,.indexOf也能查找对象。第二个可选参数用于指定开始查找的位置。

var a = { foo: &#39;bar&#39; }
var b = [a, 2]
console.log(b.indexOf(1))
// <- -1
console.log(b.indexOf({ foo: &#39;bar&#39; }))
// <- -1
console.log(b.indexOf(a))
// <- 0
console.log(b.indexOf(a, 1))
// <- -1
b.indexOf(2, 1)
// <- 1

如果你想从后向前搜索,可以使用.lastIndexOf。

操作符:in

在面试中新手容易犯的错误是混淆.indexOf和in操作符:

var a = [1, 2, 5]
1 in a
// <- true, but because of the 2!
5 in a
// <- false

问题是in操作符是检索对象的键而非值。当然,这在性能上比.indexOf快得多。

var a = [3, 7, 6]
1 in a === !!a[1]
// <- true

走近.reverse

该方法将数组中的元素倒置。

var a = [1, 1, 7, 8]
a.reverse()
// [8, 7, 1, 1]

.reverse 会修改数组本身。

参考

《Fun with JavaScript Native Array Functions》

以上就是详细介绍有趣的JavaScript原生数组函数的代码示例的内容,更多相关内容请关注PHP中文网(www.php.cn)!

성명:
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.