博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

JS---引用类型

Posted on 2013-05-23 21:52  Amy-lover  阅读(711)  评论(0编辑  收藏  举报

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只定义了两个单体内置对象:GlobalMath,不需要实例化,我们只需要直接使用它的方法和属性即可

一、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()*可能值的总数+第一个可能的值)