《JavaScript 高级程序设计》学习总结五(1)
引言:这一章节开始,我将会对JavaScript的引用类型进行总结。其篇幅会很长并且JavaScript 的引用类型是很重要的一个知识点,同样其中也不乏难以理解之处,所以我会尽量精简详细一些,同时在每章节的总结程度上也会像前面的几章一样采用分节方式,,尽量不让篇幅过长造成阅读疲劳。
Object 类型:
创建 Object 的实例有良好总方式:
1、采用 new 操作符,后跟Object 构造函数 比如:
var person =new Object();
person.name="jack";
person.age=18;
2、对象字面量表示法 :
var person={
name: jack, (这里采用逗号来分隔属性)
age:18 (最后一个属性不需要加逗号,如果添加逗号会在IE7 和早版本的 Opera 导致错误)。
};
还可以写成: 或者写成:
var person ={ var person{};
"name":"jack", person.name="jack";
"age":18 (让属性变成字符串方式也是可以的) person.age=18; 这样虽然可行,但是看起来总是怪怪的。不推荐。
}
访问对象属性:平时我们都常用点表示法,比如; person.name ;这样的方式在很多语言中也是常用的,但是在JavaScript 中我们还可以用方括号来访问这个属性,比如:person["name"]; 甚至我们还可以通过变量来访问:var personName = "jack"; 这样的好处是如果属性名中包含会导致错误
person[personName];
的字符,或者属性名使用的是关键字或者保留字,也可以使用方括号表示法,比如:person ["first name"]= "jack"; 这里"first name" 其中包含了空格,这样用点表示法是不行的,但是却可以用方括号表示法。
在平时的使用中不过如果不是特殊情况,还是用点表示法。
Array 类型:
Array 也是一个常用类型,而且比较有意思的是 ECMAScript中的 array (数组) 也是与别的语言有很大的不同。在 ECAMScript中的数组的每一项可以保存任何类型的数据,也就是说数组中我们可以第一个保存字符串,第二个保存数字等等,都是没问题的。
创建数组有两种方式:
1、 var colors=new array(20); //数组长度20
也可以直接向里面添加值: var colors =new array(red", "blue", "yellow"); 也可以省略 new 操作符 :var colors= array(20) 或者 var colors =array("red");
2、数组字面量表示法:
var color =[red","blue", "yellow"];
var color =[" "];// 创建空数组
var color =[1,2, ];//不建议,这样会创建一个包含两项或三项的数组
var color =[ , , , , ,];// 不建议,这样会创建一个包含5项或者6项的数组
ps :与对象一样,在使用数组字面量表示法时也不会调用Array 的构造函数,(firefox 3及更早版本除外)。
数组读取: 采用下标索引的方式 ;
数组的length 属性:说起length 属性大家肯定很熟悉,在很多语言中 length 都被用来表示数组的长度, 在JavaScript 中也是如此,但是不同的是 JavaScript 的length 比较特殊 (都是腰间盘,就 js 最突出)。JavaScript的length 属性不是只读的,也就是说我们可以通过JavaScript的 length 进行写入操作。比如:
var colors=new Array("red","blue","yellow");
colors.length=2;
alert(colors[2]); //undefined 这里本来数组长度是 3,但是被设置成2 ,所以最后一项被移除了,就变成 undefined 了(下标计数是从0 开始这个不多说了吧)。
再或者:
var colors=new Array("red","blue","yellow");
colors[colors.length]="pink"; //因为最后一项的位置是 length-1, 所以这里用length 就在最后又添加了一个位置
alert(colors[3]); // pink ,在后面添加了pink
colors[colors.length]="black";
alert(colors[4]); //black ,这里也让我们在知道,当把一个值放到超出当前数组大小的位置上时,数组会重新计算长度。
检测数组:
Array.isArray()方法, 比如:var colors=new Array("red","blue","yellow"); 支持这个属性的有: IE9 +、 FireFox 4+ 、Opera 10.5+和Chrome 。
alert(Array.isArray(colors)); //true
转换方法:
调用数组的toString()方法,将会返回由数组中每个值的字符串形式拼接而成的以逗号分隔的字符串,valueOf()方法返回的还是数组,与toString()是一样的结果
toLocaleString()返回的通常与toString()和valueOf()返回结果是一样的,但并不总是如此,使用toLocaleString()方法,则会去调用数组中每一项的toLocaleString()方法,而不是toString()方法。
join方法接受一个参数,即作为分隔符的字符串
例:
var
arra = [“one”,”two”];
arra.join(“||”);
//one||two
如果不给join传递参数,则返回以逗号作为分隔的字符串
注:如果数组中某一项的值为null或者undefined,则调用join,toLocaleString(),toString(),valueOf()返回的结果则使用空字符串表示。
栈方法:
说起栈我想大家都不陌生。栈是一种 (last in first out )后进先出的数据结构。而JavaScript 的数组也实现了这样的数据结构方式,使用数组的这两个方法 push() 推入 以及 pop ()弹出,就可以模仿栈的数据结构形式。
这两个用法: push()方法可以接受任意值,并把它们逐个添加到数组末尾。增加length 长度
pop() 方法则从数组末尾移除最后一项,减少数组长度。
队列方法:
队列数据结构的访问规则是FIFO (first in first out)先进先出。队列在列表末端添加数据,从列表前端移除。由于push 是向末尾添加数据,因此要模拟队列只需要一个从数组前端取得项的方法,当然,JavaScript 早就为我们准备好了 ,那就是 shift() 方法。这个方法 作用就是移除数组第一项。
使用这两个方法就可以模拟队列的数据结构形式。
同时 数组还有一个 unshift()方法,顾名思义,shift()是移除数组第一项,unshift()就是在数组前端添加。此时用pop() 方法就可以模拟队列的反方向结构形式了。
重新排序方法:
数组中已经存在两个方法可以用来直接重排序的方法: reverse() 和 sort()方法,reverse()方法会反转数组的顺序比如:
var col=[1,5,8,4,5];
col.reverse();
alert(cols); // 5 4 8 5 1
而sort()方法会从降序到升序进行排序比如:
var col=[1,5,8,4,5];
col.sort();
alert(cols); // 1 4 5 5 8
有趣的是 sort 方法会调用数组中每一个项的 toString 方法,然后再进行比较以确定如何排序,所以即使里面是数值也是先转换成字符串之后进行比较。
这里我比较奇怪的是,转换成字符串之后怎么比较。果然就看到了一种情况:
var col=[1,5,10,4,5];
colors.sort();
alert(cols); // 1 10 4 5 5 因为转换成字符串之后 “10” 比 4还靠前。所以就成了上面的情况。所以很显然,sort() 方法并不是很靠谱的方式(不知道为什么要这样设计)。不得不说,我在学习到这里的时候也是很郁闷,甚至内心是(mmp)。因为:接下来《JavaScript 高级程序设计》给我们的解答是 让sort()接收一个比较函数,这个比较函数的编写是:
function compare (){
if (value1 < value2){
return -1;
}else if( value 1>value2){
return 1;
}else{
return 0;
}
}再接着。var value =[1,10,4,5,5]
value.sort(compare);// 1 4 5 5 10
没错,书中对于这样的形式就仅仅只是这样,看到这里真是一头雾水。Excuse me ? 所以我又参考了 W3C 中对sort 的解说。(建议点击详情好好看看)。
如果调用该方法时没有使用参数,将按字母顺序对数组中的元素进行排序,说得更精确点,是按照字符编码的顺序进行排序。要实现这一点,首先应把数组的元素都转换成字符串(如有必要),以便进行比较。
如果想按照其他标准进行排序,就需要提供比较函数,该函数要比较两个值,然后返回一个用于说明这两个值的相对顺序的数字。
。
简单一点也可以这样:
function com(b,a){
return b-a
}
var colors=[2,5,10,4,5];
colors.sort(com);
alert(colors);
好吧,说实话,看到这里我还是很郁闷,在sort()里面传参数为什么就可以实现升序/降序了呢?原理是什么,我搜了很久终于在github 上找到了 “sort 实现原理 710行开始”,然后偶然看到了 justjavac 大大的文章 《从 V8 源码看 JS 数组排序的诡异问题》。当然,尴尬的是我目前还看不懂。不过也算是勉强填了坑了,知识总是慢积累的嘛。
操作方法:
concat() 方法:这个方法会先创建当前数组的一个副本,然后将其接收到的参数添加到这个副本的末尾,最后返回新的构造函数。在没有参数的情况下,它就只是复制当前副本再返回。(说起这个注意的是这个方法是复制当前数组的副本哦,切记,题外话:以前有段时间阮一锋老师的快排就被撕逼了,原因是里面用了这个方法,而且因为大家引用太多了于是就,你懂的,也不能怪人家,主要还是因为太多人不舍得自己思考过于依赖了)。
slice() 方法:它能够基于当前数组中的一个或者多个项创建一个新数组。slice ()方法可以接受 1个或两个参数,即要返回的起始位置和结束位置,在只有一个参数的情况下,slice 返回从这参数的指定位置开始到结束的所有项,如果是来个参数,那么该方法返回起始位置带到结束位置之间的项,但是不包括结束位置的项。slice() 方法并不会影响原数组。
举个例子:
var colors =["red","blue","yellow"];
colors.slice(1);
alert(colors.slice(1)); // blue yellow 从1 开始到结束,包括1.
以及:
var colors =["red","blue","yelow"];
alert(colors.slice(1,2)); // blue 从1开始到2 但是不包括2 。
如果slice () 参数中有一个是负数,则用数组长度加上该数来确定相应位置,例如 在一个包含 5个长度的数组中使用 slice( -2,-1)相等于 slice(3,4);
splice()方法:
splice 方法的主要作用就是向数组的中部插入项,但使用这种方法的方式有如下三种:
1、删除,可以删除任意数量的项,只需指定两个参数:要删除的第一项的位置和删除的项数。比如:splice( 0,2) 会删除数组前两项。
举个例子:
var colors =["red","blue","yelow"];
colors.splice(1,2);
alert(colors); //red
2、插入,可以指定位置插入任意的数量项,只需要提供三个参数:起始位置,0(要删除的项数,这里是0表示没有删除),和要插入的项。如果要插入多个项,就直接在后面添加就好。
举个例子:
var colors =["red","blue","yelow"];
colors.splice(1,0,"black","pink");
alert(colors); // red black pink blue yellow 。 从第一项开始插入,删除0 个,添加的为 black, pink
3、替换,只需要指定三个参数:起始位置,要删除的项数,和插入的项数。(看了2 其实也就了解这个实现也是一样的了)。
举个例子:
var colors =["red","blue","yelow"];
colors.splice(1,1,"black");
alert(colors); // red black yellow 从第一项开始,删除1个,插入black。
哇哦,看完 splice (),的用法,不得不感叹,活用活现的话,这个方法真的是很强大了。直接可以实现数组的 “增 删 改”。
------------------------------------------------------------------------------------------------------------------------------------------------------------------------
本节完,JavaScript 的数组真是一个内容丰富的知识点,不愧是“包罗万象”(数组的参数可以是任何类型的数据)。
恩,下一节继续对 数组的几个方法以及还有一些 其他的引用类型 的总结。