引用类型
引用类型的值(对象)是引用类型的一个实例。
一、Object类型
创建Object实例:
1 //方法一:通过new操作符创建 2 var a = new Object(); 3 a.neme = "Tom"; 4 a.age = 3; 5 //方法二:通过对象字面量创建,注意:此时的name什么的不是局部变量,'{}'相当于执行了new操作呢..... 6 var b = { 7 name: "Jerry", 8 age: 3 9 }; 10 var c = {}; //与new Object()相同 11 12 //对象字面量也是向函数传递大量参数的首选方式 13 function fun(args) { 14 if (typeof args.name == "string") { 15 //doSth 16 } 17 if (typeof args.age == 'number') { 18 //doSth 19 } 20 }
访问:
alert(a.name); alert(a["name"]); //这种语法的优点是可以通过变量访问
二、Array类型
1.数组的每一项可以保存任何类型的数据
2.数组的大小可以动态调整
创建数组:
//方式一:通过new创建 var a = new Array(6); //创建长度为6的数组 var b = new Array(1,2,6,8); //定义并初始化一个数组 //方式二:使用数组字面量 var c = [18,19,88]; var d = [];
检测是否为数组:
alert(a instanceof Array); //该方法在两种不同的全局执行环境下作检测会有问题 //因此可以使用ECMAScript新增的方法: alert(Array.isArray(a));
转换:
alert(b.join('|')); //1|2|6|8
栈方法(先进后出):
push()函数:接收任意数量的参数,并逐个添加到数组末尾,最后返回修改后数组长度。
pop():从数组末尾移除最后一项,减少数组的length值,返回移除的项。
队列方法(先进先出):
shilft():移除数组的第一项,并返回该项。
unshilt():在数组的前端添加任意个项并返回数组的长度。
重排序:
reverse():反转数组的顺序
sort():该函数调用数组每项(即使该项是数字)的toString()方法,然后比较得到的字符串(当然是按比较字符串的方式)
var a = [5,8,66,89,45,15]; alert(a.sort()); //15,45,5,66,8,89 alert(a); //15,45,5,66,8,89 会改变原数组
这不科学,所以sort()方法接收一个比较函数作为参数
操作方法:
concat()方法:创建数组副本,并把接收到的参数添加到副本末尾,最后返回副本(原数组不改变)
slice()方法:接收一个或者两个参数,起始项和结束项。复制---剪切----返回剪切后的数组
splice()方法:用于删除,插入和替换数组中的项,返回原始数组中的删除项。
splice(arg1,arg2,args3...)
arg1:起始位置
arg2:要删除的项数,插入操作时设置为0
args3:要插入的项,可以为多个
位置方法:
indexOf() lastIndexOf():都接收两个参数,要查找的项和查找起始位置的索引。
迭代方法:
ECMAScript5定义了5个迭代方法,每个方法都接收两个参数:要在每一项运行的函数和运行该函数作用域对象------影响this的值。
传入这些方法的函数会接收三个参数:数组项的值,该项在数组中的位置和数组对象本身。
1)every():对数组的每一项都运行给定函数,如果该函数对每一项都返回true则,则every()返回true
2)filter():对数组的每一项运行给定函数,返回该函数会返回true的项组成的新数组
3)forEech():对数组的每一项运行给定函数,无返回值,该操作也不会影响数组。
4)map():对数组的每一项运行给定函数,返回每次函数调用的结果组成的数组
5)some():对数组的每一项运行给定函数,如果该函数对任意一项返回true,则返回true
示例:
var a = [5,8,66,89,45,15]; var everyResult = a.every(function (item) { return item > 15; }); alert(everyResult); //false var someResult = a.some(function (value) { return value > 15; }); alert(someResult); //true var fileterResult = a.filter(function (value) { return value > 15; }); alert(fileterResult); //66,89,45
归并方法:
所谓归并方法:迭代数组的所有项,然后构件一个最终返回值。
ECMAScript5新增了两个归并数组的方法:reduce() reduceRight()两个方法都接收两个参数,一个是在数组的每一项都会调用的函数,另一个参数是作为递归的初始值。
参数一的函数接收四个参数:前一个值,当前值,项的索引,和数组对象,这个函数的返回值会作为第一个参数传给下一项。
var values = [1,2,3,4,5,6]; var sum = values.reduce(function (pre, cur) { return pre+cur; }); console.log(sum); //21
三、Date类型
ECMAScript使用UTC开始经过的毫秒数来保存时间。
创建:
var date = new Date(); //创建当前时间和日期
重要的方法:
Date.parse():传入表示日期的字符串,返回毫秒数。字符串无法解析返回NaN
Date.UTC():该函数也返回毫秒数,但该函数接收参数:年份,基于0的月份,月份中的哪一天,小时数.......
var allFives = new Date(Date.UTC(2005, 4, 5, 17, 55, 55));
注意Date的构造函数会模仿以上两个函数。
Date.now():放回当前时间毫秒数
其他方法请查看API
四、RegExp类型
ECMAScript通过RegExp类型来支持正则表达式,语法:
var expression = /pattern/flag; //用RegExp构造函数 var p = new Reg Exp('pattern', 'flag'); //注意由于RegExp构造函数模式参数是字符串,所以有时要进行双重转义。
pattern为正则表达式,flag表面正则表达式行为:
g: 表达式被应用于所有字符串,而非发现第一个时立即停止。
i: 忽略大小写
m: 多行模式
使用正则表达式字面量和使用 RegExp 构造函数创建的正则表达式不一样。在 ECMAScript 3 中,
正则表达式字面量始终会共享同一个 RegExp 实例,而使用构造函数创建的每一个新 RegExp 实例都是 一个新实例。例如:
var re = null, i; for (i=0; i < 10; i++){ re = /cat/g; re.test("catastrophe"); } for (i=0; i < 10; i++){ re = new RegExp("cat", "g"); re.test("catastrophe"); }
在第一个循环中,即使是循环体中指定的,但实际上只为/cat/创建了一个 RegExp 实例。由于实
例属性(下一节介绍实例属性)不会重置,所以在循环中再次调用 test()方法会失败。这是因为第一
次调用 test()找到了"cat",但第二次调用是从索引为 3 的字符(上一次匹配的末尾)开始的,所以
就找不到它了。由于会测试到字符串末尾,所以下一次再调用 test()就又从开头开始了。
第二个循环使用 RegExp 构造函数在每次循环中创建正则表达式。因为每次迭代都会创建一个新的
RegExp 实例,所以每次调用 test()都会返回 true。
ECMAScript 5 明确规定,使用正则表达式字面量必须像直接调用 RegExp 构造函数一样,每次都创
建新的 RegExp 实例。 IE9+、 Firefox 4+和 Chrome 都据此做出了修改。
RegExp实例属性:
global:布尔值,表示是否设置了 g 标志。
ignoreCase:布尔值,表示是否设置了 i 标志。
lastIndex:整数,表示开始搜索下一个匹配项的字符位置,从 0 算起。
multiline:布尔值,表示是否设置了 m 标志。
source:正则表达式的字符串表示,按照字面量形式而非传入构造函数中的字符串模式返回。
RegExp实例方法:
RegExp 对象的主要方法是 exec(),该方法是专门为捕获组而设计的。 exec()接受一个参数,即
要应用模式的字符串,然后返回包含第一个匹配项信息的数组;或者在没有匹配项的情况下返回 null。
返回的数组虽然是 Array 的实例,但包含两个额外的属性: index 和 input。其中, index 表示匹配
项在字符串中的位置,而 input 表示应用正则表达式的字符串。在数组中,第一项是与整个模式匹配
的字符串,其他项是与模式中的捕获组匹配的字符串(如果模式中没有捕获组,则该数组只包含一项)。
请看下面的例子。
var text = "a home a kid a fool mom and dad and baby"; var p = /mom (and dad (and baby)?)?/g var m = p.exec(text); console.log(m.index); console.log(m.input); console.log(m[0]); console.log(m[1]); console.log(m[2]); /* * 20 * a home a kid a fool mom and dad and baby * mom and dad and baby * and dad and baby * and baby * */
对于 exec()方法而言,即使在模式中设置了全局标志(g),它每次也只会返回一个匹配项。在不
设置全局标志的情况下,在同一个字符串上多次调用 exec()将始终返回第一个匹配项的信息。而在设
置全局标志的情况下,每次调用 exec()则都会在字符串中继续查找新匹配项,如下面的例子所示。
var text = "cat, bat, sat, fat"; var pattern1 = /.at/; var matches = pattern1.exec(text); alert(matches.index); //0 alert(matches[0]); //cat alert(pattern1.lastIndex); //0 matches = pattern1.exec(text); alert(matches.index); //0 alert(matches[0]); //cat alert(pattern1.lastIndex); //0 var pattern2 = /.at/g; var matches = pattern2.exec(text); alert(matches.index); //0 alert(matches[0]); //cat alert(pattern2.lastIndex); //3 matches = pattern2.exec(text); alert(matches.index); //5 alert(matches[0]); //bat alert(pattern2.lastIndex); //8
正则表达式的第二个方法是 test(),它接受一个字符串参数。在模式与该参数匹配的情况下返回
true;否则,返回 false。
ECMAScript 正则表达式不支持的特性 :
匹配字符串开始和结尾的A 和 锚①
向后查找(lookbehind) ②
并集和交集类
原子组(atomic grouping)
Unicode 支持(单个字符除外,如uFFFF)
命名的捕获组③
s(single,单行)和 x(free-spacing,无间隔)匹配模式
条件匹配
正则表达式注释
① 但支持以插入符号(^)和美元符号($)来匹配字符串的开始和结尾。
② 但完全支持向前查找(lookahead)。
③ 但支持编号的捕获组。
五、Function类型
在ECMAScript中函数实际上是对象,每个函数都是Function类型的实例,函数名实际上是一个指向函数对象的指针,不会与某个函数绑定。
函数的声明:
//方式一,函数声明 function f(a,b){ //doSth } //方式二,函数表达式 var m = function(a,b){ //doSth } //方式三,new操作符 var fun = new Function("a","b","return a + b"); //不推荐该方式
函数声明与函数表达式的区别:
解析器会率先读取函数声明,并使其在执行任何代码之前可用。
表达式则按照普通表达式的顺序执行。
但这只是执行顺序问题,作用域链不会受影响函数声明出来的f,也是一个带var的变量。
作为值的函数
函数名本来就是变量,因此函数可用作为值来使用,即可用被另一个函数当做参数、返回值。
函数的内部属性:
1)arguments
2)this:指向函数执行环境的变量对象
window.color = "red"; var o = { color: "blue" }; function sayColor(){ alert(this.color); } sayColor(); //"red" o.sayColor = sayColor; o.sayColor(); //"blue"
3)callee:该属性是一个指针,指向拥有这个arguments对象的函数。使用该属性可以使函数的执行和函数名解耦。
function factorial(num){ if (num <=1) { return 1; } else { return num * arguments.callee(num-1) } }
4)caller:ECMAScript 5支持,这个属性保存着调用当前函数的函数引用,如果是在全局作用域中调用函数,该属性为null
window.onload = function () { function outer() { inner(); } function inner() { console.log(arguments.callee.caller); } outer(); //显示outer()函数的源代码 }
函数的属性和方法:
length属性:表示函数希望接受命名参数的个数。
proptoype属性:保存所有实例方法。ECMAScript5中该属性不可枚举。
apply()和call()方法:两个方法的用途都是在特定作用域中调用函数
var a = 8; window.onload = function () { var obj = {a:99} function sum(num1, num2) { return num1 + num2 + this.a; } function sum2(num1, num2) { return sum.call(this,num1,num2); //只能这么用,不能像apply那样传入arguments或数组 } function sum3(num1, num2) { return sum.apply(this,arguments); } function sum4(num1, num2) { return sum.apply(this,[num1,num2]); } function sum5(num1, num2) { return sum.call(obj,num1,num2); //扩充函数作用域 } function sum6(num1, num2) { return sum.apply(obj,arguments); } console.log(sum2(2,2)); //12 console.log(sum3(2,2)); //12 console.log(sum4(2,2)); //12 console.log(sum5(2,2)); //103 console.log(sum6(2,2)); //103 }
ECMAScript5 定义的bind()方法:该方法会返回一个函数的实例,其this值会被绑定为传给bind()的参数
window.color = "red"; var o = { color: "blue" }; function sayColor(){ alert(this.color); } var objectSayColor = sayColor.bind(o); objectSayColor(); //blue
六、基本包装类型
所谓基本包装类型就是ECMAScript包装的三个特殊引用类型:String,Boolean,Number
每当读取一个基本类型值的时候,后台就会创建一个基本包装类型的对象,从而使我们能调用一些方法来处理数据。
var str = "The end of the world!" console.log(str.substr(3));//end of the world!"
以上代码执行过程:
1)创建一个String类型的实例
2)在实例上调用指定方法
3)销毁该实例
可以想象为代码:
var str = new String("The end of world!"); console.log(str.substring(3)); str = null;
基本包装类型与一般引用类型的主要区别就是对象的生命周期,基本包装类型只存在于执行代码的一瞬间,
执行完毕后立即被销毁。这意味着我们不能为基本包装类型添加属性和方法。
var str = "High but not dry."; str.name = "the cure"; console.log(str.name); //undefined var str2 = new String("Friday I'm in love."); str2.name = "the cure"; console.log(str2.name); //the cure
var str = "A letter to Elise"; var str2 = new String("A letter to Elise"); console.log(typeof str); //string console.log(typeof "letter"); //string console.log(typeof str2); //object
var value = "25"; var number = Number(value); //转型函数 alert(typeof number); //"number" var obj = new Number(value); //构造函数 alert(typeof obj); //"object"
一)Boolean
最常见的问题:
var falseObject = new Boolean(false); var result = falseObject && true; alert(result); //true
其实也好理解,new(调用构造函数) 出来的在赋值给变量的,永远是一个正真的引用类型,该变量的值是一个引用类型的地址。
二)Number
toFixed()方法:按照指定的小数位返回数值的字符串表示
var num = 10; alert(num.toFixed(2)); //"10.00"
toExponential()
返回以指数表示法(也称 e 表示法)表示的数值的字符串形式
toPrecision()会根据要处理的数值决定到底是调用 toFixed()还是调用 toExponential()。
三)String
length属性:字符个数
方法:
charAt()
charCodeAt()
contact(str)
str[index]
slice(index,index2)
substr(index,len):第二个参数指定返回字符串个数
substring(index,index2)
trim(str)
以上方法都不影响原字符串
localcompare(str):比较字符串,并返回-1,0,1中的一个
七、单体内置对象
内置对象:由ECMAScript实现提供,不依赖宿主环境的对象,这些对象在ECMAScript程序执行以前就已经存在。
如:Object、String、Array
一)Global对象
所有在全局域中定义的属性和函数,都是Global对象的属性。浏览器通常将Global对象作为window对象一部分加以实现。
如parseInt(),isNaN()等
1)URI编码方法()略
2)eval()略
二)Math对象
略