乐趣区

javascript高级程序设计读书笔记三

烈日炎炎,有你超甜~????????

第五章 引用类型

1.Object 类型

var person = new Object();
person.name = "her";
person.age = 17;
var person = {
    name : "her",
    age : 17
}

上面两个代码块代表了创建 Object 实例的两种实现方式。第一种是使用 new 操作符后跟 Object 构造函数;第二种是使用对象字面量表示法。

对象字面量也是向函数传递大量可选参数的首选,看下面的例子吧!

function displayInfo(args) {
    var output = "";
    if(type args.name == "string"){output += "Name:" + args.name + "\n";}
    if(type args.age == "string"){output += "Age:" + args.age + "\n";}
    alert(output);
}
displayInfo({
    name: "her",
    age: 17
});
displayInfo({name: "haha"});

上面例子中,函数 displayInfo()接受一个名为 args 的参数。这个参数可能带有一个名为 name 或 age 的属性,也可能两个属性都有或都没有。

访问对象属性的方法有两种

alert(person["name"]);
alert(person.name);

没啥区别。方括号语法的优点是可以通过变量来访问属性。

2.Array 类型

var colors = new Array();                        // 使用 Array 构造函数创建
var colors = new Array(20);                      // 创建 length 值为 20 的数组
var colors = new Array("red", "blue", "green");  // 创建一个包含三个字符串值的数组
var colors = ["red", "blue", "green"];     // 创建一个包含 3 个字符串的数组
var names = [];                            // 创建一个空数组
var values = [1,2,];                       // 不要这样!会创建一个包含 2 或 3 项的数组
var options = [,,,,,];                     // 不要这样!会创建一个包含 5 或 6 项的数组

读取的时候,要用方括号并提供响应值的基于 0 的数字索引

var colors = ["red","blue","green"];     // 定义一个字符串数组
alert(colors[0]);                        // 显示第一项
colors[2] = "black";                     // 修改第三项
colors[3] = "brown";                     // 新增第四项
var names = [];
alert(colors.length);                    //3
alert(names.length);                     //0

colors.length = 2;
alert(colors[2]);     //undefined colors 一开始有三个值,length 属性设置为 2 会移除最后一项,在访问自然就 undefined 了
colors.length = 4;
alert(colors[3]);    //undefined  colors 经过刚才删除 length 只剩下 2 了,现在又设置成 4,这个数组不存在位置 2 和 3,所以访问就是 undefined

var colors = ["red","blue","green"];     // 定义一个包含 3 个字符串的数组
colors[colors.length] = "black";         //(在位置 3)添加一种颜色
colors[colors.length] = "brown";         //(在位置 4)再添加一种颜色

检测数组的方法是 Array.isArray()方法。

if (Array.isArray()) {// 对数组执行某些操作}

数组的转换方法:

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

数组继承的 toLocaleString()、toString()和 valueOf()方法,在默认情况下都会以逗号分隔的字符串形式返回数组项。

join()方法,则可以使用不同的分隔符来构建这个字符串。只接受一个参数,即用作分隔符的字符串。

var colors = ["red","blue","green"];        // 定义一个包含 3 个字符串的数组
alert(colors.join(","));            //red,blue,green
alert(colors.join("||"));           //red||blue||green

如果不给 join()方法传入任何值,或者给它传入 undefined,则使用逗号分隔。
如果数组中的某一项的值为 null 或 undefined,那么该值在 join()、toLocaleString()、toString()和 valueOf()方法返回的结果中以空字符串表示。

栈方法,ECMAScript 为数组专门提供了 push()和 pop()方法,以便实现类似栈的行为。

var colors = ["red","blue"];     // 定义一个包含 3 个字符串的数组
colors.push("brown");            // 添加一项
colors[3] = "block";             // 添加另一项
alert(colors.length);            //4
var item =  colors.pop();        // 取得最后一项
alert(item);                     //"black"

push()方法可以接收任意数量的参数,把它们逐个添加到数组末尾,并返回修改后的数组的长度。
pop()方法则从数组末尾移除最后一项,减少数组的 length 值,然后返回移除的项。

栈数据结构的访问规则是 LIFO(后进先出),而队列数据结构的访问规则是 FIFO(先进先出)
队列在列表的末端添加项,从列表的前端移除项。
结合使用 shift()和 push()方法,可以像使用队列一样使用数组。

var colors = new Array();             // 创建一个数组
var count = colors.push("red", "green");  // 推入两项
alert(count.length);      //2

count = colors.push("black");           // 推入另一项
alert(count);       //3

var item = colors.shift();            // 从前面取得第一项
alert(item);          //"red"
alert(colors.length);     //2
alert(colors);         //green,black

var cc = colors.unshift("red");     // 从前面推入一项
alert(count);     //3

var item = colors.pop();       // 取得最后一项
alert(item);      //"black"
alert(color.length);     //2

shift 方法能够移除数组中的第一项并返回该项。
unshift 方法能在数组前端添加任意个项并返回新数组的长度。

数组中已经存在两个可以直接用的重排序方法:reverse()和 sort()。
reverse()方法会对反转数组项的顺序。
sort 方法按升序排列数组项。但它比较的是字符串

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

很明显 sort()方法不是最佳方案。因此 sort()方法可以接受一个比较函数作为参数,以便我们指定哪个值位于哪个值前面。

function compare(value1,value2) {if(value1 < value2){return -1;}else if (value1 > value2){return 1;}else {return 0;}
}
var values = [0,1,5,10,15];
values.sort(compare);        // 将函数 compare 作为参数传递给 sort()方法
alert(values);    //0,1,5,10,15

也可以通过比较函数产生降序排序的结果,只要交换比较函数返回的值即可。value1 < value2 时候,return 1;

数组的操作方法
concat() 方法可以基于当前数组的所有相创建一个新的数组。具体说,先创建当前数组的一个副本,然后将接收到的参数添加到这个副本的末尾,最后返回新构建的数组。
var colors = [“red”,”blue”,”green”]; // 定义一个包含 3 个字符串的数组
var colors2 = colors.concat(“yellow”,”black”,”brown”);
alert(colors); //red,blue,green
alert(colors2); //red,blue,green,yellow,black,brown

slice()方法,能基于当前数组中的一个或多个项创建一个新数组。能接受一或两个参数,即要返回项的起始和结束位置。
只有一个参数时,该方法返回从该参数指定位置开始到当前数组末尾的所有项;
两个参数时,该方法返回起始和结束之间的项—但不包括结束位置的项。
注意哈,该方法不会影响原始数组哟~

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

特殊情况哈~如果 slice()方法的参数中有一个负数,则用数组长度加上该数来确定相应的位置。
eg 在一个包含 5 项的数组上调用 slice(-2,-1)与调用 slice(3,4)得到的结果相同。
如果结束位置小于起始位置,返回空数组。

下面说下最强大的数组方法:splice()方法。它的主要用途时向数组的中部插入项。使用方式如下:

  • 删除:可以删除任意数量的项,只需指定 2 个参数:要删除的第一项的位置和要删除的项数。例如,splice(0,2)会删除数组中的前两项。
  • 插入:可以向指定位置插入任意数量的项,只需提供 3 个参数:起始位置,0(要删除的项数)和要插入的项。
  • 替换:可以向指定位置插入任意数量的项,且同时删除任意数量的项,只需指定 3 个参数:起始位置,要删除的项数和要插入的任意数量的项。

splice()方法会返回从原始数组中删除的项(如果没有删除任何项,则返回一个空数组)。

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

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

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

ECMAScript5 为数组实例添加了两个位置方法:indexOf()和 lastindexOf()。都接收两个参数:要查找的项和 (可选的) 表示查找起点位置的索引。
indexOf()从数组的开头 (位置 0) 开始查找,lastindexOf()从数组的末尾开始向前查找。
两个方法都返回要查找的项在数组中的位置,没找到的情况下返回 -1.
要求查找的项必须严格相等(就像使用 === 一样)。

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

var person = {name:“her”};
var people = [{name:“her”}];
var morePeople = [person];
alert(people.indexOf(person);          //-1
alert(morePeople.IndexOf(person));     //0

ECMAScript5 为数组定义了 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);
})
alert(everyResult);       //false

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

filter()利用指定函数确定是否在返回的数组中包含的某一项。
这个方法对查询符合某些条件的所有数组项非常有用。
eg 要返回一个多有数值都大于 2 的数组;

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

map()也返回一个数组,而这个数组的每一项都是在原始数组中的对应项上运行传入的函数的结果。
eg 可以给数组中的每一项乘以 2,然后返回这些乘积组成的数组

var numbers =  [1,2,3,4,5,4,3,2,1];
var mapResult = numbers.map(function(item, index, array){return (item > 2);
})
alert(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){// 执行某些操作})

ECMAScript5 还新增了两个缩小数组的方法: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;})
alert(sum);       //15

未完待续~

退出移动版