《JavaScript高级程序设计》第三版 笔记
第5章 引用类型
本章内容
·使用对象
·创建并操作数组
·理解基本的 JavaScript 类型
·使用基本类型和基本包装类型
引用类型的值(对象)是引用类型的一个实例。
在 ECMAScript 中,引用类型是一种数据结构,用于将数据和功能组织在一起。
ECMAScript 从技术上讲是一门面向对象的语言,但它不具备传统的面向对象语言所支持的类 和接口等基本结构。
引用类型有时候也被称为对象定义,因为它们描述的是一类对象所具有的属性和方法。
*虽然引用类型与类看起来相似,但它们并不是相同的概念。
对象是某个特定引用类型的实例;
新对象是使用 new 操作符后跟一个构造函数来创建的。
构造函数本身就是一个函数,只不过该函数是出于创建新对象的目的而定义的。
ECMAScript 提供了很多原生引用类型(例如Object),以便开发人员用以实现常见的计算任务。
/*使用 Object 构造函数,创建了 Object 引用类型的一个新实例,然后把该实例保存在了变量 obj 中。
构造函数 Object 为新对象定义了默认的属性和方法。*/
var obj = new Object();
5.1 Object 类型
Object 是 ECMAScript 中使用最多的一个类型;
对于在应用程序中存储和传输数据而言,它们是非常理想的选择。
在对象字面量中,使用逗号来分隔不同的属性;
最后一个属性后面不能添加逗号(最后一个属性后加逗号会在 IE7 及更早版本和 Opera 中导致错误。)。
创建 Object 实例的方式有两种:
1.new 操作符后跟 Object 构造函数。
example:
var person = new Object();
person.name = "aim";
person.name = 29;
2.使用对象字面量表示法。
对象字面量是对象定义的一种简写形式,目的在于简化创建大量属性的对象的过程。
*在通过对象字面量定义对象时,实际上不会调用 Object 构造函数。(Firefox 2 及更早版本会调用 Object 构造函数,但 Firefox 3 之后就不会了。)
example:
var person = {
name : "aim",
age : 29
};
使用对象字面量语法时,留空其花括号与 new Object() 相同,定义了只包含默认属性和方法的对象。
example:
var person = {}; //与 new Object() 相同
person.name = "aim";
person.age = 29;
使用对象字面量语法时,属性名也可以使用字符串。
example:
//创建了一个对象,包含三个属性。
var person = {
"name" : "aim",
"age" : 29,
5 : true //这里的数值属性名会自动转换为字符串。
};
向函数传递大量可选参数的首选方式–对象字面量;
这种语法要求的代码量少,而且能够给人封装数据的感觉。
example:
function displayInfo(args) {
var output = "";
if (typeof args.name == "string"){
output += "Name:" + args.name + "\n";
}
if (typeof args.age == "number"){
output += "Age:" + args.age + "\n";
}
console.log(output);
}
displayInfo({
name : "aim",
age : 29
});
displayInfo({
name : "alex"
});
这种传递参数的模式最适合需要向函数传入大量可选参数的情形;
一般来讲,命名参数虽然容易处理,但在有多个可选参数的情况下就会显示不够灵活;
最好的做法是对那些必需值使用命名参数,而使用对象字面量来封装多个可选参数。
访问对象的属性选择点表示法还是方括号表示法?
一般来说,访问对象属性都是使用点表示法。
在 JavaScript 中也可以使用方括号表示法来访问对象的属性。
使用方括号表示法时,将要访问的属性以字符串的形式放在方括号中。
优势:
1.可以通过变量访问属性。
2.如果属性名中包含会导致语法错误的字符,或者属性名使用的是关键字或保留字(属性名中是可以包含非字母非数字的),这时候就可以使用方括号法来访问它们。
example:
var person = {
name : "aim",
"second name" : "alex", //包含空格的属性名必须是字符串形式,否则会报错。(SyntaxError: missing )
"age" : 29
};
console.log(person["name"]); //aim
console.log(person.age); //29
//通过变量访问属性
var propertyName = "name";
console.log(person[propertyName]); //aim
console.log(person["second name"]); //alex
5.2 Array 类型
ECMAScript 数组的每一项可以保存任何类型的数据,包括对象;
数组的大小是可以动态调整的,即可以随着数据的添加自动增长以容纳新增数据。
创建数组的基本方式有两种:
1.使用 Array 构造函数。
如果预先知道数组长度,也可以给构造函数传递该数量,该数量会自动变成 length 属性的值;
也可以向 Array 构造函数传递数组中应该包含的项。
在使用 Array 构造函数时也可以省略 new 操作符。
example:
var colors = new Array();
var persons = new Array(10);
console.log(persons.length); //10
var fruits = new Array("apple","banana","orange");
var trees = Array(3); //创建一个包含 3 项的数组
console.log(trees.length); //3
var names = Array("aim"); //创建一个包含一项,即字符串"aim"的数组
*只给构造函数传递一个值的话,如果是数值,则会按照该数值创建包含给定项数的数组;如果传递的是其他类型的参数,则会创建包含那个值的只有一项的数组。
2.使用数组字面量表示法
数组字面量由一对包含数组项的方括号表示,多个数组项之间以逗号隔开。
*与对象一样,在使用数组字面量表示法时,也不会调用 Array 构造函数(Firefox 3 及更早版本除外)。
example:
var conputers = ["dell","hp","lenovo"];
var garbage = [];
/* 在 IE(IE 8 及之前版本)中,values 会成为包含 1、2、undefined 3个项目的数组。
在其他浏览器中, values 会成为一个包含 1、2 两个项目的数组。 */
var values = [1,2,];
console.log(values.length); //2(Firefox 57.0.4)
/* 可能会创建包含 5 项的数组(在 IE 9+、 Firefox、 Opera、 Safari、 Chrome 中),
也可能会创建包含 6 项的数组(在 IE 8 及更早版本中)。
在像这种省略值的情况下,每一项都将获得 undefined 值。这个结果与调用 Array 构造函数时传递项数在逻辑上是相同的。
但是由于 IE 的实现与其它浏览器不一致,因此强烈建议不要使用这种语法。*/
var options = [,,,,,];
console.log(options.length); //5(Firefox 57.0.4)
console.log(options[0]); //undefined
访问数组元素:
使用方括号并提供相应值的基于 0 的数字索引。
example:
var friends = ["aim","alex","hondu"];
console.log(friends[0]); //aim
console.log(friends[4]); //undefined
设置数组元素:
如果设置某个值的索引超过了数组现有项数,数组就会自动增加到该索引值加 1 的长度。
example:
var friends = ["aim","alex","hondu"];
friends[0] = "jerry";
friends[5] = "danny";
console.log(friends[0]); //jerry
console.log(friends.length); //6
length 属性:
数组的长度保存在 length 属性中,这个属性始终会返回 0 或更大的值;
length 属性不是只读的,通过设置这个属性,可以从数组的末尾移除项或向数组中添加新项;
如果设置 length 属性值小于数组长度,那么这个长度之外的数组元素会被移除,再访问会得到 undefined 值;
如果设置 length 属性值大于数组长度,则新增的每一项都会取得 undefined 值。
当把一个值放在超出当前数组大小的位置上时,数组就会重新计算其长度值,即长度值等于最后一项的索引加 1 。
利用 length 属性也可以方便的在数组末尾添加新项。
example:
var friends = ["aim","alex","hondu"];
friends[friends.length] = "jerry";
friends[friends.length] = "danny";
*数组最多可以包含 4 294 967 295 个项,如果超出这个上限值,就会发生异常。而创建一个初始大小与这个上限值接近的数组,则可能会导致运行时间超长的脚本错误。
example:
var friends = ["aim","alex","hondu"];
friends[4294967295] = "6";
console.log(friends[4294967295]); //6
console.log(friends.length); //3
friends[4294967294] = "5";
console.log(friends[4294967294]); //5
console.log(friends.length); //4294967295
var testArrayLength = new Array(4294967295); console.log(testArrayLength.length); //4294967295
var testArrayLength = new Array(4294967296);
console.log(testArrayLength.length); //RangeError: invalid array length
5.2.1 检测数组
Array.isArray() 方法:
这个方法的目的是最终确定某个值到底是不是数组,而不管它是在哪个全局执行环境中创建的。
(支持 Array.isArray() 方法的浏览器有 IE 9+、 Firefox 4+、 Safari 5+、 Opera 10.5+、 Chrome。要在尚未实现这个方法的浏览器中准确检测数组,请参考22.1.1节。)
if (Array.isArray(value)){
}
example:
var friends = ["aim","alex","hondu"];
console.log(Array.isArray(friends)); //ture
*对于一个网页,或者一个全局环境而言,使用 instanceof 操作符就可以确定某个对象是不是数组;如果网页中包含多个框架,那实际上就存在两个以上不同的全局执行环境,从而存在两个以上不同版本的 Array 构造函数。如果你从一个框架向另一个框架传入一个数组,那么传入的数组与在第二个框架中原生创建的数组分别具有各自不同的构造函数。为了解决问题, ECMAScript 5 新增了 Array.isArray() 方法。
5.2.2 转换方法
toLocaleString(), toString(), valueOf(), join() 方法。
调用数组的 toString() 方法会返回由字符串形式拼接而成的一个以逗号分隔的字符串。而调用 valueOf() 方法返回的还是数组。实际上,为了创建这个字符串会调用数组每一项的 toString() 方法。
调用 alert() 方法,alert()要接收字符串参数,所以它会在后台调用 toString() 方法,由此会得到与直接调用 toString() 方法相同的结果。
example:
var values = [1,2,3];
console.log(values.toString()); //1,2,3
console.log(values.toLocaleString()); //1,2,3
console.log(values.valueOf()); //Array [ 1, 2, 3 ]
console.log(values); //Array [ 1, 2, 3 ]
toLocaleString() 方法也经常会返回与 toString() 和 valueOf() 方法相同的值,但也不会总是如此。当调用数组的 toLocaleString() 方法时,它也会创建一个数组值的以逗号分隔的字符串。而与前两个方法唯一不同之处在于,这一次为了取得每一项的值,调用的是每一项的 toLocaleString() 方法,而不是 toString() 方法。
example:
var person1 = {
toLocaleString : function(){
return "aim";
},
toString : function(){
return "alex";
}
};
var person2 = {
toLocaleString : function(){
return "jerry";
},
toString : function(){
return "dnrry";
}
};
var people = [person1,person2];
alert(people); //alex,dnrry
console.log(people);
console.log(people.toString()); //alex,dnrry
console.log(people.toLocaleString()); //aim,jerry
数组继承的 toLocaleString(), toString(), valueOf() 方法,在默认情况下都会以逗号分隔的字符串形式返回数组项。
如果使用 join() 方法,则可以使用不同的分隔符来构建这个字符串;
join() 方法只接收一个参数,即用作分隔符的字符串,然后返回包含所有数组项的字符串;
如果不给 join() 方法传入任何值,或者给它传入 undefined,则使用逗号作为分隔符;(IE 7 及更早的版本会错误的使用字符串“undefined”作为分隔符。)
如果数组中的某一项的值是 null 或者 undefined ,那么该值在 join()、 toLocaleString()、 toString()、 valueOf() 方法返回的结果中以空字符串表示。
example:
var values = [1,2,3];
console.log(values.join("?")); //1?2?3
console.log(values.join()); //1,2,3
console.log(values.join(undefined)); //1,2,3
var someThing = [1,2,null,"hello"];
console.log(someThing.join()); //1,2,,hello
console.log(someThing.toString()); //1,2,,hello
console.log(someThing.toLocaleString()); //1,2,,hello
console.log(someThing.valueOf()); //Array [ 1, 2, null, "hello" ]
alert(someThing.valueOf()); //1,2,,hello
5.2.3 栈方法
ECMAScript 数组也提供了一种让数组的行为类似于其它数据结构的方法。具体来说,数组可以表现得就像栈一样,后者是一种可以限制插入和删除项的数据结构。栈是一种 LIFO(Last-In-First-Out,后进先出)的数据结构,也就是最新添加的项最早被移除。而栈中项的插入(叫做推入)和移除(叫做弹出),只发生在一个位置–栈的顶部。 ECMAScript 为数组专门提供了 push() 和 pop() 方法,以便实现类似栈的行为。
push() 方法:
可以接收任意数量的参数,把它们逐个添加到数组末尾,并返回修改后数组的长度。
pop() 方法:
从数组末尾移除最后一项,减少数组的 length 值,然后返回移除的项。
example:
var colors = ["red","blue"];
//push() 方法
console.log(colors.push("yellow","pink")); //4
console.log(colors.length); //4
console.log(colors.toString()); //red,blue,yellow,pink
//pop() 方法
console.log(colors.pop()); //pink
console.log(colors.toString()); //red,blue,yellow
console.log(colors.length); //3
5.2.4 队列方法
栈数据结构的访问规则是 LIFO(后进先出),而队列数据结构的访问规则是 FIFO(First-In-First-Out,先进先出)。队列在列表的末端添加项,从列表的前端移除项。由于 push() 是向数组末端添加项的方法,因此要模拟队列只需一个从数组前端取得项的方法。实现这一操作的数组方法就是 shift() ,它能够移除数组中的第一个项并返回该项,同时将数组长度减 1 。结合使用 shift() 和 push() 方法,可以像使用队列一样使用数组。
shift() 方法:
移除数组中的第一个项并返回该项,同时将数组长度减 1 。
example:
//shift()和push()方法
var languages = new Array(); //创建一个数组
var count = languages.push("chinese","japanese"); //推入两项
console.log(count); //2
count = languages.push("english"); //推入另一项
console.log(count); //3
var item = languages.shift(); //取得第一项
console.log(item); //"chinese"
console.log(languages.length); //2
console.log(languages.toString()); //japanese,english
unshift() 方法:
在数组前端添加任意个项并返回新数组的长度。
*同时使用 unshift() 和 pop() 方法,可以从相反的方向来模拟队列,即在数组的前端添加项,从数组末端移除项。
example:
//unshift()和pop()方法
var seasons = new Array(); //创建一个数组
var count = seasons.unshift("spring","summer"); //推入两项
count = seasons.unshift("autumn"); //推入另一项
console.log(count); //3
console.log(seasons.toString()); //autumn,spring,summer
var item = seasons.pop(); //取得最后一项
console.log(item); //"summer"
console.log(seasons.length); //2
*IE 7 及更早版本对 JavaScript 的实现中存在一个偏差,其 unshift() 方法总是返回 undefined 而不是数组的新长度。IE 8 在非兼容模式下会返回正确的长度。
5.2.5 重排序方法
reverse() 和 sort() 方法的返回值是经过排序之后的数组。
reverse()方法:
反转数组项的顺序。
example:
var values1 = [1,2,3,4,5];
values1.reverse();
console.log(values1); // Array [ 5, 4, 3, 2, 1 ]
var values2 = [3,5,1,8];
console.log(values2.reverse()); // Array [ 8, 1, 5, 3 ]
console.log(values2.reverse()); // Array [ 3, 5, 1, 8 ]
sort() 方法:
默认情况下按升序排列数组项–即最小的值位于最前面,最大的值排在最后面;
为了实现排序, sort() 方法会调用每个数组项的 toString() 转型方法,然后比较得到的字符串;
即使数组中的每一项都是数值, sort() 方法比较的也是字符串。
sort() 方法可以接收一个比较函数作为参数,以便我们指定哪个值位于哪个值的前面。(例如下方示例中的 compare()函数,这个比较函数可以适用于大多数数据类型。)
对于数值类型或者其 valueOf() 方法会返回数值类型的对象类型,可以使用一个更简单的比较函数。这个函数只要用第二个值减第一个值即可。(例如下方示例中的 sortNumberRise() 函数和 sortNumberDecline() 函数。)
(w3school 中对于 sort()方法的解释)
语法:
arrayObject.sort(sortby); //参数 sortby 可选,规定排序顺序,必须是函数。
在原数组上进行排序,不生成副本。
如果调用该方法时没有使用参数,则按照字符编码的顺序进行排序。
如果想按照其他标准进行排序,就需要提供比较函数,该函数要比较两个值,然后返回一个用于说明这两个值的相对顺序的数字。比较函数应该具有两个参数 a 和 b,其返回值如下:
·若 a 小于 b,在排序后的数组中 a 应该出现在 b 之前,则返回一个小于 0 的值。
·若 a 等于 b,则返回 0。
·若 a 大于 b,则返回一个大于 0 的值。
example:
var values3 = [0,1,10,5,15];
console.log(values3.sort()); // Array [ 0, 1, 10, 15, 5 ]
alert(values3); //0,1,10,15,5
var words = ["apple","aim","world","hello","emergency","english"];
console.log(words.sort()); //Array [ "aim", "apple", "emergency", "english", "hello", "world" ]
//升序排列
var values4 = [0,1,10,5,15];
function sortNumberRise(a,b) {
return a - b;
}
console.log(values4.sort(sortNumberRise)); // Array [ 0, 1, 5, 10, 15 ]
//降序排列
var values5 = [0,1,10,5,15];
function sortNumberDecline(a,b) {
return b - a;
}
console.log(values5.sort(sortNumberDecline)); // Array [ 15, 10, 5, 1, 0 ]
//升序排列
var values6 = [0,1,10,5,15];
function compare(value1,value2) {
if (value1 < value2){
return -1;
} else if (value1 > value2){
return 1;
} else {
return 0;
}
}
console.log(values6.sort(compare)); //Array [ 0, 1, 5, 10, 15 ]
5.2.6 操作方法
concat() 方法:
基于当前数组中的所有项创建一个新数组;
这个方法会先创建当前数组一个副本;
然后将接收到的参数添加到这个副本的末尾;
最后返回新创建的数组。
不影响原始数组 。
在没有传递参数的情况下;
只是复制当前数组并返回副本。
如果传递了一或多个数组,则该方法会将这些数组中的每一项都添加到结果数组中。
如果传递的值不是数组,
这些值就会被简单的添加到结果数组的末尾。
example:
var colors2 = ["red","green","blue"];
console.log(colors2.concat("yellow",["black","brown"])); //Array [ "red", "green", "blue", "yellow", "black", "brown" ]
console.log(colors2); //Array [ "red", "green", "blue" ]
slice()方法:
基于当前数组中的一个或多个项创建一个新数组;
可以接收一或两个参数,即要返回项的起始和结束位置;
在只有一个参数的情况下,返回从该参数指定位置开始到当前数组末尾的所有项;
如果有两个参数,返回起始和结束位置之间的项–但不包括结束位置的项。
如果参数中有一个负数,则用数组长度加上该数来确定相应的位置(例如在一个包含5项的数组上调用 slice(-2,-1)与调用slice(3,4)得到的结果相同)。
如果结束位置小于起始位置,则返回空数组。
不影响原始数组。
example:
var values7 = [1,2,3,4,5,6];
console.log(values7.slice()); //Array [ 1, 2, 3, 4, 5, 6 ]
console.log(values7.slice(1,3)); //Array [ 2, 3 ]
console.log(values7.slice(2)); //Array [ 3, 4, 5, 6 ]
console.log(values7.slice(3,9)); //Array [ 4, 5, 6 ]
console.log(values7.slice(-3,-1)); //Array [ 4, 5 ]
console.log(values7.slice(4,1)); //Array []
console.log(values7); //Array [ 1, 2, 3, 4, 5, 6 ]
splice()方法:
主要用途是向数组的中部插入项;
始终都会返回一个数组;
该数组中包含从原始数组中删除的项;
如果没有删除任何项,则返回一个空数组。
删除:
可以删除任意数量的项;
只需指定2个参数,要删除的第一项的位置和要删除的项数(例如 splice(0,2) 会删除数组中的前两项)。
插入:
可以向指定位置插入任意数量的项;
只需提供3个参数,起始位置、0(要删除的项数)、要插入的项;
如果要插入多个项,可以再传入第四、第五,以至任意多个项。
替换:
可以向指定位置插入任意数量的项,且同时删除任意数量的项;
只需指定3个参数,起始位置、要删除的项数、要插入的任意数量的项;
插入的项数不必与删除的项数相等。
example:
//splice() 方法
var values8 = [1,2,3,4,5];
console.log(values8.splice(1,2)); //Array [ 2, 3 ]
console.log(values8); //Array [ 1, 4, 5 ]
console.log(values8.splice(1,6)); //Array [ 4, 5 ]
console.log(values8); //Array [ 1 ]
console.log(values8.splice(6,1)); //Array []
console.log(values8); //Array [ 1 ]
console.log(values8.splice(1)); //Array []
console.log(values8); //Array [ 1 ]
console.log(values8.splice()); //Array []
console.log(values8); //Array [ 1 ]
console.log(values8.splice(1,0,7,"blue")); //Array []
console.log(values8); //Array [ 1, 7, "blue" ]
console.log(values8.splice(1,2,8,9,"green")); //Array [ 7, "blue" ]
console.log(values8); //Array [ 1, 8, 9, "green" ]
console.log(values8.splice(1,9,10)); //Array [ 8, 9, "green" ]
console.log(values8); //Array [ 1, 10 ]
console.log(values8.splice(0,1)); //Array [ 1 ]
console.log(values8); //Array [ 10 ]
var values9 = [0,1,2,3,4,5];
console.log(values9.splice(-1,2)); //Array [ 5 ]
console.log(values9); //Array [ 0, 1, 2, 3, 4 ]
console.log(values9.splice(-1,-2)); //Array []
console.log(values9); //Array [ 0, 1, 2, 3, 4 ]
5.2.7 位置方法
indexOf() 和 lastIndexOf():
这两个方法都接收两个参数:
要查找的项和(可选的)表示查找起点位置的索引;
indexOf() 方法从数组的开头(位置0)开始向后查找;
lastIndexOf() 方法从数组的末尾开始向前查找;
这两个方法都返回要查找的项在数组中的位置;
在没找到的情况下返回 -1;
在比较第一个参数与数组中的每一项时,会使用全等操作符。
支持它们的浏览器包括: IE 9+、Firefox 2+、Safari 3+、Opera 9.5+、Chrome。
example:
//indexOf() 、lastIndexOf()
var values10 = [1,2,3,4,5,4,3,2,1];
console.log(values10.indexOf(4)); //3
console.log(values10.lastIndexOf(4)); //5
console.log(values10.indexOf(4,4)); //5
console.log(values10.lastIndexOf(4,4)); //3
var person = {name:"aim"};
var people = [{name:"aim"}];
var morePeople = [person];
console.log(people.indexOf(person)); //-1
console.log(morePeople.indexOf(person)); //0
var obj1 = {name:"aim"};
var obj2 = {name:"aim"};
console.log(obj1 == obj2); //false
var arr1 = [0,1];
var arr2 = [0,1];
console.log(arr1 == arr2); //false
var arr1str = arr1.toString();
var arr2str = arr2.toString();
console.log(arr1str == arr2str); //true
5.2.8 迭代方法
ECMAScript 为数组定义了 5 个迭代方法;
每个方法都接收两个参数:
要在每一项上运行的函数和(可选的)运行该函数的作用域对象–影响 this 的值;
传入这些方法中的函数会接收三个参数:
数组项的值、该项在数组中的位置和数组对象本身;
根据使用的方法不同,这个函数执行后的返回值可能会也可能不会影响访问的返回值;
这些方法中最相似的是 every() 和 some() ,它们都用于查询数组中的项是否满足某个条件;
filter() 方法对查询符合某些条件的所有数组项非常有用;
map() 方法适合创建包含的项与另一个数组一 一对应的数组;
forEach() 没有返回值,本质上与使用 for 循环迭代数组一样。
支持这些方法的浏览器有: IE 9+、Firefox 2+、Safari 3+、Opera 9.5+、Chrome。
every():
对数组中的每一项运行给定函数,如果该函数对每一项都返回 true,则返回 true ,否则返回 false。
filter():
对数组中的每一项运行给定函数,返回该函数会返回 true 的项组成的数组。
forEach():
对数组中的每一项运行给定函数,这个方法没有返回值。
map():
对数组中的每一项运行给定函数,返回每次函数调用的结果组成的数组。
some():
对数组中的每一项运行给定函数,如果该函数对任一项返回 true ,则返回 true。
example:
//迭代方法
var values11 = [1,2,3,4,5,4,3,2,1];
//every()
var everyResult = values11.every(function(item,index,array) {
return (item > 2);
});
console.log(everyResult); //false
console.log(values11); //Array [ 1, 2, 3, 4, 5, 4, 3, 2, 1 ]
//some()
var someResult = values11.some(function(item,index,array) {
return (item > 2);
});
console.log(someResult); //true
console.log(values11); //Array [ 1, 2, 3, 4, 5, 4, 3, 2, 1 ]
//filter
var filterResult = values11.filter(function(item,index,array) {
return (item > 2);
});
console.log(filterResult); //Array [ 3, 4, 5, 4, 3 ]
console.log(values11); //Array [ 1, 2, 3, 4, 5, 4, 3, 2, 1 ]
//map()
var mapResult = values11.map(function(item,index,array) {
return item*2;
});
console.log(mapResult); //Array [ 2, 4, 6, 8, 10, 8, 6, 4, 2 ]
console.log(values11); //Array [ 1, 2, 3, 4, 5, 4, 3, 2, 1 ]
//forEach
var forEachResult = values11.forEach(function(item,index,array) {
return item+1;
});
console.log(forEachResult); //undefined
console.log(values11); //Array [ 1, 2, 3, 4, 5, 4, 3, 2, 1 ]
var arr2 = new Array();
values11.forEach(function(item,index,array) {
arr2[index] = item+1;
});
console.log(arr2); //Array [ 2, 3, 4, 5, 6, 5, 4, 3, 2 ]
console.log(values11); //Array [ 1, 2, 3, 4, 5, 4, 3, 2, 1 ]
values11.forEach(function(item,index,array) {
var arr3 = new Array();
arr3[index] = item+1;
});
console.log(arr3); //ReferenceError: arr3 is not defined
5.2.9 缩小方法
reduce() 和 reduceRight():
ECMAScript 5 还新增了两个缩小数组的方法;
这两个方法都会迭代数组的所有项;
然后构建一个最终返回的值;
reduce() 方法从数组的第一项开始,逐个遍历到最后;
reduceRight() 则从数组的最后一项开始,向前遍历到第一项;
这两个方法都接收两个参数:
一个在每一项上调用的函数和(可选的)作为缩小基础的初始值;
传给 reduce() 和 reduceRight() 的函数接收 4 个参数:
前一个值、当前值、项的索引和数组对象;
这个函数返回的任何值都会作为第一个参数自动传给下一项;
第一次迭代发生在数组的第二项上,因此第一个参数是数组的第一项,第二个参数就是数组的第二项;
使用 reduce() 还是 reduceRight() ,主要取决于要从哪头开始遍历数组,除此之外,它们完全相同。
支持这两个缩小函数的浏览器有: IE 9+、Firefox 3+、Safari 4+、Opera 10.5 和 Chrome。
example:
//reduce()
/*第一次执行回调函数,prev 是 1, cur 是 2。
* 第二次,prev 是 3(1 加 2 的结果),cur 是 3(数组的第三项)。
* 这个过程会持续到把数组中的每一项都访问一遍,最后返回结果。
* reduceRight() 的作用类似,只不过方向相反而已。*/
var values12 = [1,2,3,4,5];
var sum2 = values12.reduce(function(prev,cur,index,array) {
return prev + cur;
});
console.log(sum2); //15
//reduceRight()
var sum3 = values12.reduceRight(function(prev,cur,index,array) {
return prev + cur;
});
console.log(sum3); //15