《JavaScript 闯关记》之累组

数组是价值的稳步聚集。每个值叫做一个素,而每个元素于多次组吃发生一个职务,以数字代表,称为索引。

JavaScript
数组是无类型的,数组元素得以是轻易档次,并且与一个数组中之两样因素呢恐怕发生例外之种。数组的因素还为或是目标要外数组。

JavaScript数组是动态的,根据需要它会增强或裁减,并且于开创数组时毫无声明一个永恒的轻重缓急或者在三番五次组大小变化时绝不重新分配空间。

JavaScript
数组可能是稀疏的,数组元素的目录不必然要连接的,它们中间可以出空缺。每个JavaScript数组都有一个length属性。针对非稀疏数组,该属性就是数组元素的个数。针对稀疏数组,length比所有元素的目要十分。

JavaScript 数组是 JavaScript
对象的奇异形式,数组索引实际上与刚刚是整数的属性名差不多。通常,数组的兑现是由此优化的,用数字索引来访问数组元素一般的话比看常规的目标属性要赶早多。

数组继承自 Array.prototype 中的特性,它定义了同一模仿丰富的数组操作方法。

缔造数组

好用频繁组字面量和 new 关键字来创造数组。

行使频繁组字面量创建数组(推荐)

var empty = [];                 // 没有元素的数组
var primes = [2, 3, 5, 7, 11];  // 有5个数值的数组
var misc = [1.1, true, "a"];    // 3个不同类型的元素

// 数组直接量中的值不一定要是常量,可以是任意的表达式
var base = 1024;
var table = [base, base+1, base+2, base+3];

// 也可以包含对象直接量或其他数组直接量
var b = [[1, {x:1, y:2}], [2, {x:3, y:4}]];

留意,不要忽略数组字面量的结尾一个元素,仅因为逗号结尾。下面几乎只案例,在不同的浏览器下,可能会见被识别成2只要素,也发出或识别成3个因素,而造成程序bug。例如:

var nums = [,,,];               // 不好的写法
var names = ["stone",,];        // 不好的写法
var colors = ["red","green",];  // 不好的写法

使用 new 关键字创建数组

使用 new 关键字调用构造函数 Array()
是创立数组的其余一样种植办法,可以据此三栽艺术调用构造函数。例如:

// 调用时没有参数
var a = new Array();

// 调用时有一个数值参数,它指定长度
var a = new Array(10); 

// 显式指定多个数组元素或者数组的一个非数值元素
var a = new Array(5, 4, 3, 2, 1, "testing");

数组元素的朗诵与描绘

使用 []
操作符来访问数组中的一个元素。数组的援位于方括号的左边。方括号中凡是一个返非负整数值的擅自表达式。使用该语法既可以读而足以形容数组的一个要素。例如:

var a = ["world"];     // 从一个元素的数组开始
var value = a[0];      // 读第0个元素
a[1] = 3.14;           // 写第1个元素
var i = 2; 
a[i] = 3;              // 写第2个元素
a[i + 1] = "hello";    // 写第3个元素
a[a[i]] = a[0];        // 读第0个和第2个元素,写第3个元素

告牢记,数组是目标的例外形式,可以吗那个创立任意名字的性质。但万一下的习性是频繁组的目,数组的异样表现就是是将因需要更新她的length属性值。

只顾,可以动用负数或非整数来索引数组。这种气象下,数值转换为字符串,字符串作为属性名来用。既然名字不是休因整数,它就是只能作为常规的目标属性,而休数组的目。同样,如果恰巧使用了是非负整数之字符串,它就作为数组索引,而无对象属性。当使用的一个浮点数和一个整数相等时情况也是均等的。例如:

a[-1.23] = true;  // 这将创建一个名为"-1.23"的属性
a["1000"] = 0;    // 这是数组的第1001个元素
a[1.000]          // 和 a[1] 相等

实际上数组索引仅仅是目标属性名的同一种植奇特类型,这意味 JavaScript
数组没有「越界」错误的概念。当试图询问任何对象被无设有的特性时,不会见报错,只会博得
undefined 值。

疏散数组

疏散频组便是含有从0开始的莫连续索引的数组。通常,数组的 length
属性值代表数组中元素的个数。如果数组是稀疏的,length
属性值大于元素的个数。可以用 Array()
构造函数或简捷地指定数组的索引值大于当前底数组长度来创造稀疏数组。

a = new Array(5);   // 数组没有元素,但是 a.length = 5
a = [];             // 创建一个空数组,a.length = 0
a[1000] = 0;        // 添加一个元素,a.length 被自动更新为1001

足足稀疏的数组通常以贯彻上较稠密的数组更缓慢、内存利用率还胜,在如此的数组中觅元素的工夫及健康对象属性的查找时间一样长。

内需专注的凡,当省略数组直接量中的价值时(使用连续的逗号,比如 [1,,3]
),这时所获取的数组也是稀疏数组,省略掉的值是匪有的:

var a1 = [,'1','2'];    // 此数组长度是3 
var a2 = [undefined];   // 此数组包含一个值为 undefined 的元素 
console.log(0 in a1);   // false,a1 在索引0处没有元素
console.log(0 in a2);   // true,a2 在索引0处有一个值为 undefined 的元素 

了解稀疏数组是询问 JavaScript
数组的真正面目的均等有。尽管如此,实际上你所遇的绝大多数 JavaScript
数组不是稀疏数组。并且,如果你实在遇见了疏散数组,你的代码很可能像比非稀疏数组一样来比其,只不过它们包含部分
undefined 值。

数组长度

每个数组有一个 length 属性,就是此特性使其区别为健康的 JavaScript
对象。针对稠密(也就是非稀疏)数组,length
属性值代表数组中元素的个数。其值比数组中极其充分之目大1。例如:

[].length             // 0,数组没有元素
['a','b','c'].length  // 3,最大的索引为2,length 为3

当数组是稀疏的常常,length
属性值大于元素的个数。而且有关这我们可以说之合呢尽管是数组长度保证大于它每个元素的索引值。或者,换一种说法,在勤组中(无论稀疏与否)肯定找不至一个因素的索引值大于或顶它的长。为了保这个规则不转变,数组有三三两两个突出之表现。

  • 首先只如同上面的叙说:如果为一个数组元素赋值,它的索引 i
    大于或等于现有数组的长时,length 属性的值将安装也 i+1
  • 其次单突出的所作所为就是是设置 length 属性为一个低于当前长的非负整数
    n 时,当前数组中那些索引值大于或顶 n 的要素用从中删除。例如:

a = [1,2,3,4,5];     // 从5个元素的数组开始
a.length = 3;        // 现在 a 为[1,2,3]
a.length = 0;        // 删除所有的元素。a 为[ ]
a.length = 5;        // 长度为5,但是没有元素,就像 new Array(5)

尚可以将反复组的 length
属性值设置为超越其眼前底尺寸。实际上这不会见为数组中补充加新的因素,它只是于屡次组尾部创建一个缺损的区域。

在 ECMAScript 5中,可以用 Object.defineProperty() 让数组的 length
属性变成单纯读的。例如:

a = [1,2,3];                                            // 从3个元素的数组开始
Object.defineProperty(a, "length", {writable: false});  // 让 length 属性只读
a.length = 0;                                           // a 不会改变

数组元素的丰富与去

咱们曾见了添加数组元素最简易的主意,为新索引赋值。例如:

a = []           // 开始是一个空数组
a[0] = "zero";   // 然后向其中添加元素
a[1] = "one";

呢足以利用 push() 方法以反复组末尾长一个还是多单要素。例如:

a = [];                 // 开始是一个空数组
a.push("zero");         // 在末尾添加一个元素。a = ["zero"]
a.push("one", "two");   // 再添加两个元素。a = ["zero", "one", "two"]

可像删除对象属性一样采取 delete 运算符来删除数组元素。例如:

a = [1,2,3]; 
delete a[1];   // a在索引1的位置不再有元素
1 in a         // => false: 数组索引1并未在数组中定义
a.length       // => 3: delete操作并不影响数组长度

瞩目,对一个数组元素运用 delete 不见面改数组的 length
属性,也不见面用元素于高索引处移下来填充已抹属性留下的空白。如果起数组中除去一个因素,它就变成稀疏数组。

数组遍历

使用 for 循环是百分之百历数组元素最广大的方。例如:

var keys = Object.keys(o);   // 获得 o 对象属性名组成的数组
var values = []              // 在数组中存储匹配属性的值
for(var i = 0; i < keys.length; i++) {  // 对于数组中每个索引
    var key = keys[i];                  // 获得索引处的键值
    values[i] = o[key];                 // 在 values 数组中保存属性值
}

每当嵌套循环或任何属性好重大的内外文中,可以视这种基本的数组遍历需要优化,数组的长度应该只询问同一涂鸦而未每次循环都设查询。例如:

for(var i = 0, len = keys.length; i < len; i++) {
   // 循环体仍然不变
}

这些事例假设数组是黑压压的,并且存有的要素都是官数据。否则,使用数组元素之前应先行检测其。例如:

for(var i = 0; i < a.length; i++) {
    if (!a[i]) continue;    // 跳过 null、undefined 和不存在的元素
    if (!(i in a)) continue ;   // 跳过不存在的元素
    if (a[i] === undefined) continue;   // 跳过 undefined 和不存在的元素
    // 循环体
}

还可以以 for-in
循环处理稀疏数组。循环每次将一个可枚举的属性名(包括反复组索引)赋值给循环变量,不存在的目将无见面遍历到。例如:

for(var index in sparseArray) {
   var value = sparseArray[index];
   // 此处可以使用索引和值做一些事情
}

但由于 for-in 循环能够枚举继承的属于性名,如添加至 Array.prototype
中的方法。基于这个缘故,在反复组上无该以 for-in
循环,除非动用额外的检测方法来过滤不思只要之性。例如:

for(var i in a) {
    // 跳过继承的属性
    if (!a.hasOwnProperty(i)) continue;

    // 跳过不是非负整数的 i
    if (String(Math.floor(Math.abs(Number(i)))) !== i) continue;
}

JavaScript 规范允许 for-in
循环以不同的逐一遍历对象的性能。通常数组元素的遍历实现是升序的,但无能够担保一定是这般的。如果数组同时有对象属性和数组元素,返回的属性名好可能是本创建的顺序而无数值的轻重顺序。如何处理是题材的实现,各个浏览器都非同等,如果算法依赖让遍历的各个,那么最好不要使
for-in 而用健康的 for 循环。

ECMAScript
5定义了部分遍历数组元素的初办法,按照索引的逐一以单传递让定义之一个函数。这些主意吃不过常用的便是
forEach() 方法。例如:

var data = [1,2,3,4,5];     // 这是需要遍历的数组
var sumOfSquares = 0;       // 要得到数据的平方和
data.forEach(function(x) {  // 把每个元素传递给此函数
    sumOfSquares += x*x;    // 平方相加
});
console.log(sumOfSquares);  // 55,1 + 4 + 9 + 16 + 25

数组检测

给一定一个不解的目标,判定其是否为数组通常十分实惠。在 ECMAScript
5受到,可以利用 Array.isArray() 函数来举行就档子业务。例如:

Array.isArray([])   // true
Array.isArray({})   // false

不过,在 ECMAScript 5原先,要区别数组和非数组对象十分窘迫。typeof
运算符对数组返回
"object"(并且于除了函数以外的保有目标还是如此)。instanceof
操作符也只好用于简单的气象。例如:

[] instanceof Array     // true
({}) instanceof Array   // false

使用 instanceof 的问题是当 Web
浏览器被来或产生差不多单窗体存在。每个窗体都发生自己的 JavaScript
环境,有温馨之大局对象。并且,每个全局对象有协调的同样组组织函数。因此一个窗体中之靶子将无容许是另外窗体中之构造函数的实例。窗体之间的混淆不常发生,但这个题目足就证明
instanceof 操作符不能够说是一个可靠的数组检测方法。

解决方案是检查对象的类属性,对数组而言该属性的价总是 "Array",因此在
ECMAScript 3中 isArray() 函数的代码可以如此写。例如:

var isArray = Array.isArray || function(o) {
    return typeof o === "object" && Object.prototype.toString.call(o) === "[object Array]";
};

数组方法

ECMAScript 3和 ECMAScript 5在 Array.prototype
中定义了有些格外有因此底操作数组的法。

转换方法

具备目标都持有 toLocaleString()toString()valueOf()
方法。其中,调用数组的 toString()valueOf()
方法会返回相同之价,即出于数组中每个值的字符串形式拼接而变成的一个缘逗号分隔的字符串。实际上,为了创造是字符串会调用数组每一样件的
toString() 方法。例如:

var colors = ["red", "blue", "green"];  // 创建一个包含3个字符串的数组
alert(colors.toString()); // red,blue,green
alert(colors.valueOf());  // red,blue,green
alert(colors);            // red,blue,green

以这边,我们率先显式地调用了 toString()valueOf()
方法,以便回到数组的字符串表示,每个值的字符串表示拼接成了一个字符串,中间为逗号分隔。最后一行代码直接将数组传递让了
alert()。由于 alert()倘收下字符串参数,所以她见面当后台调用
toString() 方法,由此会拿走与直调用 toString() 方法同样的结果。

另外,toLocaleString() 方法经常也会见回去跟 toString()valueOf()
方法一致之价值,但为不连续这么。当调用数组的 toLocaleString()
方法时,它为会见创造一个再三组值的以逗号分隔的字符串。而与前方少独方法唯一的不同之处在于,这无异于坏为取各级一样件的价值,调用的是各国一样码之
toLocaleString() 方法,而不是 toString() 方法。例如:

var person1 = {
    toLocaleString : function () {
        return "Nikolaos";
    },
    toString : function() {
        return "Nicholas";
    }
};

var person2 = {
    toLocaleString : function () {
        return "Grigorios";
    },
    toString : function() {
        return "Greg";
    }
};

var people = [person1, person2];
alert(people);                           // Nicholas,Greg
alert(people.toString());                // Nicholas,Greg
alert(people.toLocaleString());          // Nikolaos,Grigorios

数组继承的 toLocaleString()toString()
valueOf()计,在默认情况下还见面坐逗号分隔的字符串的花样返回数组项。而要采用
join() 方法,则可以以不同的相间符来构建这个字符串。join()
方法只有收到一个参数,即用作分隔符的字符串,然后返回包含所有数组项的字符串。例如:

var colors = ["red", "green", "blue"];
console.log(colors.join(","));    // red,green,blue
console.log(colors.join("||"));   // red||green||blue

若数组中的某某平宗之价值是 null 或者 undefined,那么该值在
join()toLocaleString()toString()valueOf()
方法返回的结果中因为空字符串表示。

栈方法

库是相同栽
LIFO(Last-In-First-Out,后进先出)的数据结构,也就算是时髦添加的起极其早于移除。push()
方法可吸纳任意数量的参数,把它逐个添加到数组末尾,并回修改后频繁组的尺寸。而
pop() 方法虽然从数组末尾移除最后一项,减少数组的 length
值,然后回移除的宗。结合 push()pop()
方法,就可像栈一样使用数组。例如:

var colors = [];                            // 创建一个数组
var count = colors.push("red", "green");    // 推入两项
console.log(count);                         // 2,数组的长度

count = colors.push("black");               // 推入另一项
console.log(count);                         // 3,数组的长度

var item = colors.pop();                    // 取得最后一项
console.log(item);                          // "black"
console.log(colors.length);                 // 2,数组的长度

队方法

队列是同栽
FIFO(First-In-First-Out,先进先出)的数据结构,队列在列表的背后添加项,从列表的前端移除项。shift()
方法则于数组前端移除第一桩,减少数组的 length
值,然后回来移除的起。结合 push()shift()
方法,就足以像队列一样用数组。例如:

var colors = [];                            // 创建一个数组
var count = colors.push("red", "green");    // 推入两项
console.log(count);                         // 2,数组的长度

count = colors.push("black");               // 推入另一项
console.log(count);                         // 3,数组的长度

var item = colors.shift();                  // 取得第一项
console.log(item);                          // "red"
console.log(colors.length);                 // 2,数组的长度

JavaScipt 还也数组提供了一个 unshift() 方法。顾名思义,unshift()
shift()
的用途相反,它能于勤组前端添加任意个宗并回新数组的长度。因此,同时采用
unshift()pop()
方法,可以于相反的可行性来效仿队列,即于数组的前端添加项,从数组末端移除项。

重排序方法

数组中出有限独还排序的主意:reverse()sort()reverse()
方法可以反转数组元素的一一。例如:

var values = [1, 2, 3, 4, 5];
values.reverse();
console.log(values);  // 5,4,3,2,1

sort()
方法可以依照升序排列数组元素(即无限小的值位于最前面,最酷之价值消除在最终当)。sort()
方法以排序的长河遭到见面调用每个数组元素的
toString(),然后比较得到的字符串,以确定什么排序。即使数组中的各国一样桩都是数值,sort()
方法较的呢是字符串,例如:

var values = [0, 1, 5, 10, 15];
values.sort();
console.log(values);     // 0,1,10,15,5

这种排序方式于很多状下还无是顶尖方案,因此 sort()
方法可吸纳一个比较函数作为参数,以便我们指定哪个值位于哪个价值的前面,以下就是一个简练的比函数。例如:

function compare(value1, value2) {
    if (value1 < value2) {
        return -1;
    } else if (value1 > value2) {
        return 1;
    } else {
        return 0;
    }
}

斯比函数接收两单参数,如果第一只参数应该放在第二独之前则赶回一个负数,如果少个参数相等则回回0,如果第一单参数应该放在第二只下则归一个正数。它可以适用于大部分情景,只要将该看做参数传递给
sort() 方法即可。例如:

var values = [10, 5, 1, 0, 15];
values.sort(compare);
console.log(values);   // 0,1,5,10,15

对数值类或者其 valueOf()
方法会返回数值类的对象类型,可以使用一个更简约的比较函数。这个函数只要用第二独值减第一个值即可。例如:

function compare(value1, value2){
    return value2 - value1;
}

是因为较函数通过返回一个仅次于零、等于零或超出零之价来震慑排序结果,因此减法操作就好适量地拍卖所有这些情况。

操作方法

JavaScript 为操作都包含在三番五次组中的因素供了多方法。其中,concat()
方法可以根据当前数组中的富有项创建一个初数组。具体来说,这个方法会先创造当前数组一个副本,然后将收到至之参数上加到此副本的末梢,最后回到新构建的数组。在并未让
concat()
方法传递参数的情状下,它才是复制当前数组并返回副本。如果传递让
concat()
方法的凡一律要多只数组,则该方法会将这些数组中之各一样码都增长到结果数组中。如果传递的价值未是累累组,这些价值就是会见给概括地抬高到结果往往组的末尾。例如:

var colors = ["red", "green", "blue"];
var colors2 = colors.concat("yellow", ["black", "brown"]);

console.log(colors);     // red,green,blue
console.log(colors2);    // red,green,blue,yellow,black,brown

下一个办法是
slice(),它会冲当前数组中之同要多个宗创建一个新数组。slice()
方法可以接受平等要么有限个参数,即只要回去项的开局与终止位置。在只有发生一个参数的事态下,slice()
方法返回从该参数指定位置上马至当前数组末尾的装有项。如果发一定量个参数,该法返回起始与结束位置之间的项,但未包了位置的起。注意,slice()
方法无会见潜移默化原始数组。例如:

var colors = ["red", "green", "blue", "yellow", "purple"];
var colors2 = colors.slice(1);
var colors3 = colors.slice(1,4);

console.log(colors2);   // green,blue,yellow,purple
console.log(colors3);   // green,blue,yellow

如果 slice()
方法的参数中产生一个负数,则就此数组长度加上该数来确定相应的职位。例如,在一个含5码之数组上调用
slice(-2,-1) 与调用 slice(3,4)
得到的结果同样。如果得了位置小于起始位置,则回空数组。

产一个术是
splice(),它的主要用途是往数组的中心插入元素,主要出以下3种植使方法。

  • 抹:可以去任意数量之项,只需要点名2单参数:起始位置与而刨除元素的多少。例如,splice(0,2)
    会删除数组中之前头片宗。
  • 插入:可以向指定位置插入任意数量之宗,只待提供3单参数:起始位置、0(要抹元素的多少)和要插入的元素。如果一旦插入多个元素,可以另行盛传第四、第五,以至任意多只要素。例如,splice(2,0,"red","green")
    会从此时此刻数组的职2开插入字符串 "red""green"
  • 轮换:可以向指定位置插入任意数量之宗,且以删除任意数量的项,只待点名3只参数:起始位置、要删减元素的数码以及假设插入的素。插入的项数不必和删除的项数相等。例如,splice (2,1,"red","green")会去时往往组位置2的起,然后再度于位置2始插入字符串
    "red""green"

splice()
方法始终都见面回一个累组,该数组中寓从原始数组中去除的起(如果没去除任何项,则回一个空数组)。下面的代码展示了上述3栽采取
splice() 方法的点子。例如:

var colors = ["red", "green", "blue"];
var removed = colors.splice(0,1);       // 删除第一项
console.log(colors);                    // green,blue
console.log(removed);                   // red,返回的数组中只包含一项

removed = colors.splice(1, 0, "yellow", "orange");  // 从位置1开始插入两项
console.log(colors);                    // green,yellow,orange,blue
console.log(removed);                   // 返回的是一个空数组

removed = colors.splice(1, 1, "red", "purple");     // 插入两项,删除一项
console.log(colors);                    // green,red,purple,orange,blue
console.log(removed);                   // yellow,返回的数组中只包含一项

职务方法

ECMAScript 5吧数组实例添加了零星个职务方法:indexOf()
lastIndexOf()。这简单只点子还收下两独参数:要寻找的项和(可选的)表示找起点位置的目录。其中,indexOf()
方法从数组的上马(位置0)开始通往后查找,lastIndexOf()
方法虽然从数组的最终开始上查找。

立马简单个点子还回到要摸的项于屡次组中的位置,或者在尚未找到的情事下回到回
-1。在比较第一只参数和数组中的各国一样桩时,会利用全等操作符;也就是说,要求寻找的起必须严格等(就如以
=== 一样)。例如:

var numbers = [1,2,3,4,5,4,3,2,1];
console.log(numbers.indexOf(4));          // 3
console.log(numbers.lastIndexOf(4));      // 5
console.log(numbers.indexOf(4, 4));       // 5
console.log(numbers.lastIndexOf(4, 4));   // 3

var person = { name: "Nicholas" };
var people = [{ name: "Nicholas" }];
var morePeople = [person];
console.log(people.indexOf(person));      // -1
console.log(morePeople.indexOf(person));  // 0

迭代艺术

ECMAScript
5吧数组定义了5个迭代方法。每个方法还收两单参数:要于每一样宗达到运行的函数和(可选的)运行该函数的作用域对象。传入这些办法被之函数会接收三独参数:数组项的值、该项在三番五次组吃的岗位和数组对象自我。根据使用的方式不同,这个函数执行后的返回值可能会见呢说不定无会见潜移默化看的返值。以下是即刻5只迭代方法的作用。

  • every(),对数组中之各级一样件运行为定函数,如果该函数对每一样起都回
    true ,则返回 true
  • filter(),对数组中的各国一样项运行于定函数,返回该函数会回 true
    的项整合的数组。
  • forEach(),对数组中的各国一样桩运行为定函数。这个办法无回去值。
  • map(),对数组中之各一样码运行为定函数,返回每次函数调用的结果成的数组。
  • some(),对数组中的各国一样项运行于定函数,如果该函数对无一件返回
    true ,则返回 true

上述办法还不见面修改数组吃之隐含的价。在这些方法被,最相似之是 every()
some(),它们还用于查询数组中之宗是不是满足某个条件。对 every()
来说,传入的函数必须对各级一样桩都回到 true,这个办法才返回
true;否则,它就是回来 false。而
some()主意则是设传入的函数对数组中之有一样宗返回 true,就会见返回
true。例如:

var numbers = [1,2,3,4,5,4,3,2,1];
var everyResult = numbers.every(function(item, index, array){
    return (item > 2); 
});
console.log(everyResult);   // false

var someResult = numbers.some(function(item, index, array){
    return (item > 2);
});
console.log(someResult);    // true

脚还看无异扣 filter()
函数,它以指定的函数确定是不是以回去的数组中蕴藏的有平宗。例如:

var numbers = [1,2,3,4,5,4,3,2,1];
var filterResult = numbers.filter(function(item, index, array){
    return (item > 2);
});
console.log(filterResult);  // [3,4,5,4,3]

map()
也归一个屡屡组,而这数组的各一样码都是在原始数组中的照应项上运行传入函数的结果。例如,可以为数组中之各级一样项乘以2,然后回到这些乘积组成的数组。例如:

var numbers = [1,2,3,4,5,4,3,2,1];
var mapResult = numbers.map(function(item, index, array){
    return item * 2;
});
console.log(mapResult);     // [2,4,6,8,10,8,6,4,2]

末了一个办法是
forEach(),它只是对数组中的各国一样桩运行传入的函数。这个方式无回到值,本质上和使用
for 循环迭代数组一样。例如:

var numbers = [1,2,3,4,5,4,3,2,1];
numbers.forEach(function(item, index, array){
    //执行某些操作 
});

压缩术

ECMAScript 5尚新增了一定量只压缩数组的主意:reduce()
reduceRight()。这片单道ECMAScript还见面迭代数组的有着项,然后构建一个说到底回的值。其中,reduce()
方法从数组的率先桩开始,逐个遍历到最后。而 reduceRight()
则从数组的尾声一码开始,向前遍历到第一起。

立刻片独道还收下两个参数:一个当各级一样件达到调用的函数和(可选的)作为缩小基础之初始值。传于
reduce()reduceRight()
的函数接收4独参数:前一个价、当前价、项之目和数组对象。这个函数返回的外价值都见面作为第一独参数自动传于下一致项。第一糟迭代发生在屡组的次码上,因此首先独参数是屡屡组的首先宗,第二个参数就是频繁组的第二项。

使用 reduce() 方法可以实行求数组吃所有值之与之操作。例如:

var values = [1,2,3,4,5];
var sum = values.reduce(function(prev, cur, index, array){
    return prev + cur; 
});
console.log(sum); // 15

第一不成实行回调函数,prev是1,cur是2。第二次于,prev是3(1加2的结果),cur是3(数组的老三码)。这个历程会随地到管数组中之每一样宗都看同全,最后回来结果。

reduceRight() 的企图类似,只不过方向相反而已。例如:

var values = [1,2,3,4,5];
var sum = values.reduceRight(function(prev, cur, index, array){
    return prev + cur;
});
console.log(sum); // 15

使用 reduce() 还是
reduceRight(),主要在要由哪头开始遍历数组。除此之外,它们完全相同。

关卡

姣好下面3独数组去还法。

// 挑战一,一维数组
var arr = [2,3,4,2,3,5,6,4,3,2];
var unique = function(arr){
    // 待实现方法体
}
console.log(unique(arr)); // [2,3,4,5,6]

// 挑战二,二维数组
var arr = [2,3,4,[2,3,4,5],3,5,[2,3,4,2],4,3,6,2];
var unique = function(arr){
    // 待实现方法体
}
console.log(unique(arr)); // [2,3,4,5,6]

// 挑战三,三维数组或 n 维数组
var arr = [2,3,4,[2,3,[2,3,4,2],5],3,5,[2,3,[2,3,4,2],2],4,3,6,2];
var unique = function(arr){
    // 待实现方法体
}
console.log(unique(arr)); // [2,3,4,5,6]

更多

体贴入微微信公众号「劼哥舍」回复「答案」,获取关卡详解。
关注
https://github.com/stone0090/javascript-lessons,获取最新动态。