1 引用类型是一种数据结构,用来将数据和功能组织在一起
2 对象是某个特定的引用类型的实例,实例的创建是使用new操作符,后面跟上构造函数
3 构造函数与函数的区别,构造函数和函数在定义上没有什么区别,唯一的区别就是调用的方式不同,任何函数,只要是通过new操作符调用的,那么它都可以作为构造函数,任何函数,如果不是通过new操作符调用的,那它就是普通的函数,为了区分函数和构造函数,我们一般将构造函数的首字母大写
4 原生引用类型有5种:Object类型、Array类型、Date类型、RegExp类型、Function类型
5 基本包装类型:与引用类型唯一的区别就是对象生存期,使用new操作符创建的引用类型的实例,在执行流离开当前作用域之前都一直保存在内存中,而自动创建的基本包装类型的对象,只存在于一行代码执行的瞬间,然后被销毁,因此我们不能给基本包装类型的实例添加属性和方法
6 基本包装类型有3种:Boolean类型、Number类型、String类型
7 内置对象:由ECMAScript实现提供的、不依赖于宿主环境的对象,这些对象在ECMAScript程序执行之前就已经存在了,如Date、Array和String等
8 单体对象:单体就是我们常说单例,单体是Javascript中最基础也是最常用的模式之一。它把代码组织为一个逻辑单元,这个逻辑单元的代码可以通过单一的变量进行访问,单体对象只有一个实例。
9 单体内置对象(单例内置对象):ECMA-262只定义了两个单体内置对象:Global和Math,不需要实例化,我们只需要直接使用它的方法和属性即可
一、Object类型
1.1 Object的实例主要用来存储和传输数据
1.2 创建方式:第一new Object();第二使用对象字面量{},对象字面量是一种定义对象的简写形式,主要是为了简化创建包含大量属性的对象的过程
var obj_01=new Object();//第一种创建Object实例的方式 obj_01.name="Jim"; obj_02.age=20; obj={//第二种创建Object实例的方式 "name":"Jhon", "age":18 };
1.3 使用new操作符创建Object实例和使用对象字面量创建Object实例的区别:对象字面量方式实际上别没有调用Object构造函数(Firefox浏览器除外)
1.4 对象字面量给人封装数据的感觉,因此开发者更倾向于这种方式
1.5 对象字面量方式也可以传递大量可选参数
function display(arg){ var output=""; if(arg.name){ output+="Name:"+arg.name+" "; } if(arg.age){ output+="age:"+arg.age; } alert(output); } display({ "name":"Jim", "age":20 });
二、Array类型
2.1 JS中的数组也是数据的有序列表,但是JS中数组的每一项可以保存任何类型的数据,而且数组大小动态可调,可以随着数据的添加而自动增长
2.2 创建Array实例的方式:第一new Array();第二使用数组字面量表示法:var color=[];
var color=new Array(); var color=new Array(4);//创建包含4个数据项的一个数组,每个数据项都是undefined var color=new Array("red","green","yellow");//创建一个包含3个数据项的数组, var color=Array();//可以省略new操作符 var color=Array(4);//创建包含4个数据项的一个数组,每个数据项都是undefined var color=Array("red","green","yellow");//创建一个包含3个数据项的数组 /*第二种方式,数组字面量表示法*/ var color=[];//创建一个空数组 var color=["red","yellow"];
2.3 访问方式
color[0]="black"; /*可以赋值,改变值,也可以读取第0个数据项的值*/
2.4 length属性
var color=new Array(); color[color.length]="red";//可以利用length属性,在数组的末尾添加新的数据项 color.length=3; alert(color[2]);//可以通过改变length属性为color数组添加或者移除数据项
2.5 我们在JS---基本概念一节中提到,所有的对象都有的属性和方法,回顾一下constructor属性,hasOwnProperty方法(给定的属性是否在该实例中),isPrototypeOf方法(传入的对象是否是调用该方法对象的原型),propertyIsEnumerable方法以及toString方法和valueOf方法
2.6 Array也有上述方法和属性,其中toString方法和valueOf方法会返回数组的字符串表示,每一项拼接成一个字符串,中间用逗号分隔
var color=new Array(); color[color.length]="red";//可以利用length属性,在数组的末尾添加新的数据项 color[color.length]="black";//可以利用length属性,在数组的末尾添加新的数据项 alert(color.toString());//"red,black"
2.7 数组也可以模拟栈(后进先出),而栈中元素的移除和推入,都发生在栈顶(数组的末尾),即末尾添加,末尾移除,方法push()和pop(),其中push()方法返回推入新的数据项后,数组的长度,pop()方法返回移除的数据项
2.8 数组也可以模拟队列(先进先出),末尾添加,前端移除,方法push()和shift(),另外还有unshift(),该方法是指在数组前端添加新的数据项,并返回数组长度
var color=new Array(); alert(color.push("red","black","green"));//"3",添加新的数据项后,数组的长度 alert(color.pop());//"green" alert(color.shift());//"red" alert(color.unshift("yellow"));//"2"
2.9 反转和排序:reverse()和sort(),返回操作过的数组,reverse():12345变成54321; sort():按照升序排列数据项,注意是将每一项转换成字符串后,按照字符串的顺序进行排序
var color=new Array(); color.push(1,2,3,4,5); alert(color.reverse());//"5,4,3,2,1" alert(color.sort());//"1,2,3,4,5" color=[10,4,35]; alert(color.sort());//"10,35,4",这个排序是按照字符串排的,不是数字大小的顺序
2.10 真正意义的数组的sort方法
function campare(v1,v2){ return v1-v2; } var color=[10,4,35]; alert(color.sort(campare));//"4,10,35"
2.11 concat()方法:基于当前数组中的所有项创建一个新的数组,具体来说,先创建当前数组一个副本,然后将接收到的参数添加到这个副本末尾,最后返回新构建的这个数组,该方法并不影响原有的数组
var color=[10,4,35]; alert(color.concat("23","44"));//"10,4,35,23,44" alert(color);//"10,4,35"
2.12 slice方法:基于当前数组中的一项或者多项创建一个新数组,该方法也不会影响原有的数组,参数返回项的起始位置和结束位置,不包括结束位置的数据项
var color=[10,4,35,23,44]; alert(color.slice(1,3));//"4,35" alert(color);//"10,4,35,23,44"
2.13 splice方法,有删除,插入,替换三项功能,全部都是对原有数组的操作
2.14 splice删除:参数:要删除项的位置和删除的项数,例如splice(0,2):删除该数组的第一项和第二项
2.15 splice插入:参数:起始位置,0,要插入的项
2.16 splice替换:参数:起始位置,删除的项数,要插入的项
var color=[10,4,35,23,44]; alert(color.splice(0,2));//“10,4” alert(color.splice(3,0,3,33)); alert(color);//"35,23,3,33" alert(color.splice(1,2,39,90));//23,44
三、Date类型
3.1 创建一个日期对象:var time=new Date();该方法将自动获取当前日期和时间,如果想设定特定的时间和日期,传入表示该日期的毫秒作为参数
3.2 为了简化对特定日期对象的创建,给出了方法Date.parse(),参数为表示该特定日期的字符串--”月/日/年“,返回值是表示该日期的毫秒数
alert(Date.parse("2/3/1000"));//-30607401600000
3.3 Date.UTC()也返回给定日期的毫秒数,但是与Date.parse()不同,它的参数分别是年份、基于0的月份、月中的哪一天(1-31),小时数(0-23)、分、秒、毫秒
3.4 Date对象的toString():返回带有时区信息的日期和时间,时间一般以军用时间(0-23)表示
3.5 Date对象的toLocaleString():与浏览器设置的地区相适应的格式返回日期和时间
3.6 Date对象的valueOf():返回表示日期的毫秒数,在我们进行日期比较的时候,可以使用该方法
3.7 常用方法getTime getMonth,getDate,getDay,getHours,getMinutes,getSeconds,以及所有的set方法
四、RegExp类型
4.1 创建RegExp实例的方式:第一,使用字面量形式var p=/\[bc\]at/i;第二,使用RegExp构造函数方式:var p=new RegExp("\\[bc\\]at","i");
4.2 var expression=/pattern/flags;其中pattern部分是正则表达式,flags部分是用来表明正则表达式的行为,匹配模式支持下面三种标志
4.3 g---全局模式(global),即模式将被应用于所有字符串;i-----表示不区分大小写(case-insensitive)模式;m---多行(mulitiline)模式,即到达一行的末尾,继续查找下一行
4.4 RegExp实例的属性:global---表示十分设置了g标志;ignoreCase---表示是否设置了i标志;lastIndex---表示开始搜索下一个匹配项的字符为止;mulitiline--表示是否设置了m标志;source--正则表达式的字符串表示,按照字面量形式的字符串模式返回
var p=/\[bc\]at/i; alert(p.global);//false alert(p.ignoreCase);//true alert(p.lastIndex);//0 alert(p.multiline);//false alert(p.source);//"\[bc\]at"
4.5 RegExp实例的方法:exec()和test()
4.6 exec():参数是要应用该正则表达式的字符串,返回第一个匹配项信息的数组,没有匹配项的时候返回null,该数组有两个属性input表示应用该正则表达式的字符串,index表示匹配项在字符串中的位置
4.7 test():参数字符串,在模式与该参数匹配的情况下返回true,否则,返回false
4.8 RegExp实例继承的toString()和toLocalString()方法返回正则表达式的字面量
五、Function类型
5.1 每一个函数都是Function类型的实例,与其他引用类型的实例一样具有属性和方法
5.2 由于函数是对象,因此函数名只是一个指向函数对象的指针,不会与某个函数绑定,因此一个函数可以有多个名字
5.3 函数的定义方式有三种:第一函数声明语法,第二种函数表达式,第三种,使用new操作符,最后一个参数是函数体
function sum(v1,v2){ return v1+v2; }//函数声明法定义函数 var sum=function(v1,v2){ return v1+v2; };//函数表达式 var sum=new Function("v1","v2","return v1+v2"); //使用这种方式,导致解析两次代码,第一次是解析常规ECMAScript代码,第二次解析是解析传入构造函数中的字符串,因此使用这种方式性能不好
5.4 函数表达式与函数声明的区别:解析器在向执行环境加载数据时,解析器会率先读取函数声明,并使其在执行任何代码之前可用,至于函数表达式,则必须等到解析器执行到它所在的代码行,才会真正被解析执行
alert(sum(10,10));//20 function sum(v1,v2){ return v1+v2; }//函数表达式法定义函数
alert(sum(10,10));//出错 var sum=function(v1,v2){ return v1+v2; }//函数表达式法定义函数
5.5 由于函数名本身就是一个变量,因此函数也可以当做值来使用,即可以讲函数作为参数传递给另一个函数,也可以将函数作为另一个函数的返回值
function callSum(someFun){//somFun函数作为参数传递 return someFun(arguments[1],arguments[2]); //somFun函数作为了callSum函数的结果返回 } function sum(v1,v2){ return v1+v2; } alert(callSum(sum,10,10));
5.6 注意函数名后面加上小括号和不加小括号的区别:函数名后面不加小括号是指该函数的指针,即该函数对象在堆内存中的地址,在函数名后面加上小括号是指对该函数的执行
5.7 arguments属性:是一个类数组对象,包含着传入函数的所有参数,该对象有callee属性,是一个指针,指向拥有这个arguments对象的函数,避免了函数体内的代码和函数名的紧耦合
function factorial(num){ if(num<=1){ return 1; }else{ return num*factorial(num-1); } } secondFactorial=factorial; factorial=function(){ return 0; }; alert(secondFactorial(5));//0 //factorial这个函数名就与函数内的代码紧紧地耦合在一起,factorial以后不能再有其他的值,不能再指向其他的对象
function factorial(num){ if(num<=1){ return 1; }else{ return num*arguments.callee(num-1); } } secondFactorial=factorial; factorial=function(){ return 0; }; alert(secondFactorial(5));//120 //现在即使factorial的值改变,仍然可以调用该函数
5.8 this属性:函数在执行时所处的作用域
var v="global_variable"; var o={v:"local_variable"}; function show(){ alert(this.v); } o.show=show; o.show();//local_variable
5.9 函数的length属性:表示函数希望接收到的命名参数的个数,arguments.length是指函数实际接收到的参数的个数
5.10 函数的prototype属性:prototype属性是保存引用类型所有实例方法的真正所在,即诸如toString和valueOf等方法实际上都保存在prototype名下,在创建自定义引用类型以及实现继承时,prototype属性极为重要
5.11 每个函数都包含两个非继承而来的方法:apply()和call():都是在特定的作用域中调用函数,实际上等于设置函数体内this对象的值
5.12 apply():两个参数,第一个是运行函数的作用域,第二个参数是一个数组[]或者是arguments对象apply(this,[n1,n2,n3])或者apply(this,arguments)
5.13 call():第一个参数没有变化,但是第二个参数必须逐个列举出来call(this,n1,n2,n3)
var v="global_variable"; var o={ v:"local_variable", }; function show(){ alert(this.v); } show.apply(this);//global_variable show.apply(o);//local_variable
5.14 toString()和toLocalString()以及valueOf()始终返回的是函数的代码
5.15 arguments.callee.caller属性指向调用当前函数的函数,来实现对调用栈的追溯
六、基本包装类型
6.1 实际上,每当读取一个基本类型值的时候,后台就会创建一个对应的基本包装类型的对象,让我们可以调用一些方法来操作这些数据
6.2 再次申明基本包装类型与引用类型的区别是对象的生存期不同,使用new操作符创建的引用类型的实例,在执行流离开当前作用域之前都一直保存在内存中,而自动创建的基本包装类型的对象,则仅存在于一行代码的执行瞬间,然后立即被销毁,因此我们不能在给基本类型值添加属性和方法
var s="text"; s.color="text"; alert(s.color);//undefined
6.3 永远不要使用Boolean对象的原因:1,布尔表达式中的所有对象都会被转换成true,2,typeof操作符对基本类型返回"boolean",但是对引用类型返回"object"
var falseObject=new Boolean(false); var falseValue=false; var result=falseObject&&true; alert(result);//true alert(typeof falseValue);//boolean alert(typeof falseObject);//object alert(falseObject instanceof Boolean);//true
6.4 Number类型,重写了toString方法:参数传递一个表示基数的参数,告诉它返回几进制数值的字符串形式
6.5 Number类型,toFixed()方法,按照指定的小数位返回数值的字符串表示
6.6 Number类型,toExponential()方法,返回以指数表示法表示的数值的字符串形式,参数是指定输出结果中小数的位数
6.7 Number类型,toPrecision()方法,参数是表示数值的所有数字的位数(不包括指数部分)
var num=10; alert(num.toString());//10 alert(num.toString(2));//1010 alert(num.toString(16));//a alert(num.toFixed(2));//10.00 alert(num.toExponential(1));//1.0e+1 alert(num.toPrecision(1));//1e+1 alert(num.toPrecision(2));//10 alert(num.toPrecision(3));//10.0
6.8 String类型
6.8.1 charAt()和charCodeAt():参数字符位置,其中charAt()以单字符字符串的形式返回给定位置的那个字符,而charCodeAt()返回的是指定位置字符的字符编码
6.8.2 substring():第一个参数指定字符开始的位置,第二个位置指定字符结束的位置,不包括该位置;substr()方法第二个参数是指定返回字符串的字符个数,但这两种方法否不改变原字符串,所有对字符串的操作:concat,slice,substring,substr,都对原字符串没有影响,只有splice方法会改变原字符串
6.8.3 indexOf()和lastIndexOf():从一个字符串中搜索给定的子字符串,只不过indexOf方法是从开头搜索,而lastIndexOf方法是从字符串的末尾向前搜索,这两种方法都可以接受第二个参数,指定搜索的起始位置,但是搜索的方向仍然不变
6.8.4 toLowerCase和toUpperCase转换大小写,另外还有方法toLocaleLowerCase和toLocaleUpperCase是针对特定地区的实现,少数语言会应用特殊的规则
6.8.5 match方法:只接受一个参数正则表达式或者RegExp对象,返回值是一个数组是正则表达式捕获到的匹配的字符串
6.8.6 search方法:返回字符串中第一个匹配项的索引
6.8.7 replace方法:参数1一个RegExp对象或者一个字符串,参数2一个字符串或者一个参数,如果第一个参数是字符串,那么只会替换第一个子字符串,如果要替换所有的字符串,必须提供一个正则表达式,并指定全局标志
6.8.8 String的静态方法fromCharCode方法:接收一个或者多个字符编码,然后将它们转换成一个字符串
6.8.9 localCompare方法:比较两个字符串
七、内置对象
7.1 Global对象
7.1.1 encodeURI方法:对URI(通用资源标识符)进行编码,以便发送给浏览器,主要用于整个URI的编码,而encodeComponentURI主要用于URI中的某一段进行编码,另外encodeURI方法不会对本身属于URI的特殊字符进行编码,例如冒号、正斜杠、问号等,而encodeComponentURI方法则会对它发现的任何非标准字符进行编码
7.1.2 encodeURI的编码结果是除了空格编码成20%,其他字符都原封不动,而encodeComponentURI则是对所有非字母和数字的字符进行编码
7.1.3 eval方法:好像是一个完整的ECMAScript解析器,它只接受一个参数,即要执行的ECMAScript字符串,当解析器发现代码中调用eval方法时,它会将传入的参数当作实际的ECMAScript语句解析,然后把解析结果插入到原位置,通过eval方法执行的代码被认为是包含该次调用的执行环境的一部分,因此被执行的代码具有与该执行环境相同的作用域链
7.2 Math对象
7.2.1 Math对象的属性:Math.PI,Math.E,Math.SQRT2(2的平方根),Math.SQRT1_2(1/2的平方根)等
7.2.2 min和max方法:确定一组数值中的最小值和最大值
7.2.3 Math.ceil()向上舍入,Math.floor()向下执行舍入,Math.round()四舍五入
7.2.4 random方法:返回0-1之间的一个随机数,不包括0和1。值=Math.floor(Math.random()*可能值的总数+第一个可能的值)