第五章 引用类型
- Object类型
- Array类型
- Date类型
- RegExp类型
- Function类型
- 基本包装类型
- 单体内置对象
- 小结
5.1 Object类型
1.创建Object实例的方式有两种:
//第一种是使用new操作符后跟Object构造函数。
var person - new object ();
person.name = "WiFi_Uncle";
person.age = 24;
//第二种是使用**对象字面量**表示法
var person = {
name : "WiFi_Uncle",
age : 24 //注意: 此处无逗号。否则IE7之前和Opera报出错
};
若使用对象字面量表示法时,如果留空其花括号,则可以定义只包含默认属性和方法的对象
访问属性:
alert(person["name"]);//优点: 可以使用变量来访问属性
alert(person.name);//
var propertyName = name;
alert(person[propertyName]);
若变量中含有空格 如first name 或包含非字母非数字的, 使用方括号表示法,一般使用点表示法
5.2 Array类型
1. ECMAScript 数组的每一项可以保存任何类型的数据
2. 创建数组的基本方式有两种,第一种是使用Array构造函数
var color = new Array ();
var brand = new Array (20); //指定length
var name = new Array("Lisa", "Lily", "WiFi");
// 使用Array构造方法时,可以将new省略 不建议。
var person = Array();
第二种是数组字面量表示法
var color = [“red”, “yellow”, “green”];
var color = [];
数组的length属性是可读写的。
color.lennth = 4;
利用length属性可以方便的在数组末尾添加新项,如下所示:
var color = ["red", "gray", "green"];
color.length = "yellow";
//由于数组最后一项的索引始终是length-1,因此下一个新项的位置就是length //length会自动变化
5.2.1 检测数组
if(value instanceof Array){
//code;
}
//判断基本数据类型用typeof 检测引用类型用instanceof
问题: 它假定只有一个全局执行环境,多个框架就会出问题
于是 ECMAScript 新增Array.isArray()方法
if(Array.isArray(value)){
//code
}
5.2.2 转换方法
所有对象都具有 toLocaleString()、toString()、valueOf()方法
toString()方法会返回/由数组中的每个值的/字符串形式/拼接而成的/一个以逗号分隔的/字符串
valueOf()返回的还是数组
toLocaleString()
5.2.3 栈方法
//栈--> 后进先出LIFO(Last In First Out)
var colors = ["red", "gray", "green"];
var count = colors.push("white", "yellow");//返回是修改后的长度 count = 5 此时colors = ["red", "gray", "green", "white", "yellow"];
var item = colors.pop();//返回的移除的最后一项
5.2.4 队列方法
//队列--> 先进先出FIFO(First In First Out)
var item = colors.shift();//取得第一项
var count = colors.unshift("gray");//在前面添加
//unshift() 在数组前端添加任意个项,并返回新数组的长度。
/*****************小总结下栈和队列***************/
var names = ["Lily", "Nancy","WiFi","Jon"];
/*栈 后进先出LIFO 两个方法: push()压入、pop()弹出。
* 操作的是arr[length-1]的位置(一个的情况)
*/
var count = names.push("Tom");
console.log("push-----> count = " + count);//返回的是length count = 5
console.log(names);//此时names = ["Lily", "Nancy","WiFi","Jon","Tom"];
var item = names.pop();
console.log("pop-----> item = " + item);
//返回的是弹出的项 item = "Tom", names = ["Lily", "Nancy","WiFi","Jon"];
/*队列 先进先出FIFO 方法: shift()弹出首个、unshift()压到最前面
* 操作的是arr[0]的位置(一个的情况)
*/
var names = ["Lily", "Nancy", "WiFi", "Jon"];
var item = names.shift();
console.log("shift-----> item = " + item);//Lily
var count = names.unshift("Tom");
console.log("unshift-----> count = " + count); // 5
![直接在浏览器上写name会有问题](http://img.blog.csdn.net/20160730135534986)
//原因我不晓得。知情的朋友留个言,谢谢!
![运行结果](http://img.blog.csdn.net/20160730135632419)
//利用unshift()和pop()反向模拟队列。即从数组前面arr[0]添加项,从数组末端arr[length-1]移除项
var myNumber = [3,4,5,6,7];
var count = myNumber.unshift(0,1,2);
console.log(myNumber);//0,1,2,3,4,5,6,7
var item = myNumber.pop();//一次只能pop一项
console.log(myNumber);//0,1,2,3,4,5,6
5.2.5 重排序方法
两个直接用来重排序的方法 reverse()和sort()
默认情况下,sort() 方法按升序(比较的是字符串)
var num = [0, 5, 1, 10, 15];
num.sort();
alert(num);//结果并非是0,1,5,10,15 而是0,1,10,15,5. 原因是sort比较的是字符串
/* 因此,sort()方法可以接收一个比较函数作为参数,以便我们指定哪个值位于哪个值的前面
** 比较函数接收两个参数,如果第一个参数应该位于第二个参数之前则返回一个负数,相等返回0,在之后就返回正数
*/
function compare(value1, value2){
return value2 - value1; //降序则改为value1 - value2;
}
var num = [0, 5, 1, 10, 15];
num.sort(compare);
alert(num);//0,1,5,10,15
//若只是想反转数组,而不用排序就用reverse()
var num = [0, 5, 1, 10, 15];
num.reverse();
alert(num);//15,10,1,5,0
5.2.6 操作方法
方法一、concat()方法可以基于当前数组中的所有项创建个新数组,简单点就是创建个副本,原来的数组不会动。
/**/
//可接收0个、1个或多个参数,没有参数就相当于复制当前数组,返回当前数组的副本
//参数若是值,就直接加到副本数组的末尾。参数若是数组,则将数组中的每一项加到副本末尾
var arr = [1,2,3,4,5];
var arr2 = arr.concat(6,[7,8,9]);
alert(arr);//1,2,3,4,5 原数组不变
alert(arr2);//1,2,3,4,5,6,7,8,9
方法二、slice()它能够基于当前数组中的一项或多个项创建一个新数组。接收一个参数或者两个参数,即返回项的起始位置和结束位置。不传则到末尾。如有2参,结束位置并不包括结束位置所在项(理解从0开始)。注意 不影响原数组
var colors = ["yellow", "red", "green", "blue", "purple"];
var colors2 = colors.slice(2);
var colors3 = colors.slice(1,3); //color.slice(-4,-2);//倒着数就好
alert(colors2); //green,blue,purple
alert(colors3); //red,green
/*若slice()方法参数中有负数,则用改数组长度加上该数来确定相应的位置。
**若结束位置小于起始位置,则返回空
**若第一个参数为负数,数组长度加上该数仍小于0,则起始位置为0(自己稍微测试下得出来的,不保证正确性)。
**若第二个参数为负数,数组长度加上该数仍小于0,则返回空(同上)。
*/
方法三、算是数组中最强大的方法了。。。splice()方法,主要用途是向数组中间插入项
但使用该方法的方式有如下三种。操作原数组,若之后还要用到原数组,记得备份!!!!
- 删除: 可以删除任意数量的项,只需指定2个参数: 要删除第一项的位置和要删除的项的数目。
举个栗子,splice(0,2); //删除数组的前两项 - 插入: 可以给指定位置插入任意数量的项。3+个参数,起始位置,0(要删除的项数为0项,也就是不删除)和要插入的项。如果要插入多个项,则把项作为第四、第五,以致任意多个项。
举个栗子: splice(2, 0, “red”, “yellow”, “green”); //在位置2依次插入red, yellow,green - 替换 可以在指定位置删除任意多项,且同时删除任意多项。3个参数。 (startPos, delNum, insertNum) delNum 可以和insertNum不相等
举个栗子: splice(2, 1, “red”, “green”);//删除位置2的1项,再从位置2插入red,green
注意: splice()方法始终返回一个从原始数组删除的项的数组,若没有删除项返回即为空。
简单点说,就是删了什么就返回了什么,没删就返回空。
5.2.7 位置方法
ECMAScript 5为数组实例添加了两个位置方法indexOf 和lastIndexOf()。都接收两个参数:要查找的项和表示查找起始位置的索引(可选) 找到返回项的所在位置,否则返回-1。 使用全等操作符比较,类似===
var person = { name: "wifi" };
var people = [{ name: "wifi" }];
var morePeople = [person];
alert(people.indexOf(person)); //-1 不懂???完全相等也要比较引用?
alert(morePeople.indexOf(person)); //0
alert({a:1} === {a:1});//也是false 原因是引用不同?有知道的朋友,请留个言告知,谢谢!
5.2.7 迭代方法
ECMAScript5为数组定义了5个迭代方法。每个方法都接收两个参数: 要在每一项上运行的函数和运行该函数的作用域对象(可选)—-影响this的值。每一项运行的函数包含三个参数: 数组项的值、该项在数组中的位置和数组对象本身。以下是五个方法的作用(简单的说)
- every(): 对数组中每一项运行指定函数,如果该函数每一项都为true,则返回true,否则false。
- filter(): 对数组中每一项运行指定函数, 返回该函数会返回true的项组成的数组(筛选出true的项)
- forEach(): 对数组中每一项运行指定函数, 没有返回值。
- map(): 对数组中每一项运行指定函数, 返回每次函数调用的结果组成的数组
- some(): 对数组中每一项运行指定函数, 如果该函数对任一项返回true就返回true
以上方法都不会改变原数组的值。
小结下5个方法 - every() 可以理解成 &&,全为真则真
- filter()筛选,筛选出真的项组成的数组
- forEach() 看意思就是对每一个做特定的操作
- map() 映射 不管结果是什么,都返回一个由结果组成的数组,并不只是true false
- some 可以理解 || 或操作,有一个为真则为真
举个栗子
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); //ture
var filterResult = numbers.filter(function(item, index, array){
return (item > 2);
});
alert(filterResult); //[3,4,5,4,3]
var mapResult = numbers.map(function(item, index, array){
return (item * 2);
});
alert(mapResult); //[2,4,6,8,10,8,6,4,2]
numbers.forEach(function(item, index, array){
alert(item);//执行的代码片
}); // 每个弹一次
5.2.7 归并方法
reduce()和reduceRight()。这两个方法都会迭代数组的所有项,然后构建一个最终的返回值。reduce()从下标0开始,往后迭代执行。reduceRight从下标[length-1]开始往前迭代执行
都接收两个参数:一个在每一项上都调用的函数和作为归并基础的初始值。传个reduce和reduceRight()的函数接收4个参数:前一个值、当前值、项的索引和数组对象。这个函数返回的任何值都会作为第一个参数自动传个下一项。第一次迭代发身在数组的第二项上,因此,第一个参数是数组的第一项,第二个参数是数组的第二项。
举个栗子:求数组中所有值的和
var arr = [1,2,3,4,5,6];
var sum = arr.reduce(function(prev, cur, index, array){
return prev + cur;
});
alert(sum); //21
5.3 Date类型
Date类型使用的是UTC(Coordinated Universal Time) 国际协调时间(CTU?怪怪的)
//创建个日期对象
var myDate = new Date();//不传参,则获取当前时间对象
/* 创建特定的时间对象
** 参数格式:
**
- "月/日/年", 如"7/30/2016"
- "英文月名 日,年",如"July 30,2016" 月和日中间没逗号,为空格
- "英文星期几 英文月名 日 年 时:分:秒 时区"
- ISO8601扩展格式YYYY-MM-DDTHH:mm:ss:sssZ 例如2016-07-30T00:00:00 兼容ECMA5才支持
*/
var someDate = new Date("7/30/2016");
alert(someDate);
//Date.now()方法,表示调用这个方法是的日期和时间的毫秒数
//举个栗子
var start = Date.now; //取得开始时间
doSomeThing(); //调用函数
var end = Date.now; //取得结束时间
var result = end - start;//函数花了多久时间
5.3.1 继承的方法
5.3.2 日期格式化的方法
toDateString() //显示星期几、月、日和年
toTimeString() //时、分、秒和时区
toLocaleDateString() //以特定于地区的格式显示星期几、月、日和年
toLocaleTimeString() //时、分、秒(无时区)
toUTCString() //显示完整的UTC日期
5.3.3. 日期/时间组件方法
/*格式大体下面这样
* 获取 get + year、month、date···
* 设置 set + year、month、date···
* 获取UTC getUTC + year、month、date···
* 设置UTC setUTC + year、month、date···
*
* 注意:
* 1. 获取年份需加Full ,如getFullYear(),getUTCFullYear();
* 2. 返回数: 月份0~11,天数1~31、星期0~6(日~六),时分秒都是0开始
* 3. 设置数: 设置年份必须是4位数。设置秒数>59就会增加分,设置分>59就会增加小时数,以此类推 s->m->h->date->month->year
* 5. Day是星期,Date才是日期,经常容易混淆!
*/
5.4 RegExp类型
ECMAScript通过RegExp类型来支持正则表达式(regular expression)
//创建正则表达式
var exp = / pattern / flags; ---------字面量
var exp = new RegExp("pattern","flags") ------ RegExp构造函数(要元字符**双重转义!!!**)
/*模式(pattern)为正则表达式,
* 标志(flags)有三个标志,分别是g,i,m (全局global、忽略大小写case-insensitive、多行multiline)
* g - 执行全文的搜索(而不是在找到第一个就停止查找,而是找到所有的匹配)。
* i - 执行不区分大小写的匹配。
* m - 多行模式
* 表达式不加flags会怎么样???
*/
var p1 = /at/g; //匹配字符串中所有的"at"的实例
var p2 = /[bc]at/i; //匹配第一个"bat"或"cat",不区分大小写
var p3 = /.at/gi; //匹配所有以"at"结尾的3个字符的组合,不区分大小写。注意:是3个!
模式中使用的元字符必须转义 元字符:{ [ ( \ ^ $ | ) ? * + . ] }
var p2 = /\[bc\]at/i; //匹配第一个"[bc]at",不区分大小写
var p = new RegExp("[bc]at", "i") //匹配第一个"bat"或“cat”等同于 var p = /[bc]at/i;
注意: 传递给RegExp构造函数的两个参数都是字符串(不能把正则表达式字面量传递给RegExp构造函数)。由于RegExp构造函数的模式参数都是字符串,所有岁字符都必须双重转义,已经转义过的字符也是如此,例如\n (字符\在字符串中通常要转义为\,而正则表达式字符串中要变成\\)
字面量模式 等价的字符串
/ [ bc ] at/ “/
/ .at / “/ \.at / “
5.4.1 RegExp实例属性 ####
RegExp的每个实例都具有下列属性
- global: 布尔值 g
- ignoreCase: 布尔值 i
- multiline 布尔值 m
- lastIndex: 整数,表示开始搜索下一个匹配性的字符位置,从0开始。
- source: 正则表达式的字符串表示,按照字面量形式而非传入构造函数中的字符串模式返回。
var p = /\[bc\]at/i;
alert(p.global); // false;
alert(p.source); // "/\[bc\]at/i"
var p2 = new RegExp("/\\[bc\\]at/", "i");
alert(p2.source; // "/\[bc\]at/i"
可见,source属性保存的是规范形式的字符串,即字面量形式的所用的字符串
5.4.2 RegExp实例方法
RegExp对象的主要方法是exec();
/*未完····/
5.4.3 RegExp构造函数属性
这些属性分别有一个长属性和短属性(Opera除外,不支持短属性,现在不知···)
长属性名 短属性名 说 明
input
lastMatch
&
lastParen
+leftContext
`
rightContext
∗multiline
’
5.4.4 模式的局限性 ####
/RegExp/
5.5 Function类型
函数实际上是对象。每个函数都是**Function类型的实例**,而且都与其他引用类型一样具有属性和方法。
由于函数是对象,因此**函数名**实际上也是一个**指向函数对象的指针**。
使用**函数声明**语法定义
function sum(num1 + num2){
return num1 + num2;
}
**函数表达式**语法定义
var sum = function (num1 + num2){
return num1 + num2;
}; //有分号
**注意:**使用不带圆括号的函数名是访问函数指针,而不是调用函数。