javascritp学习笔记(四)----引用类型
引用类型有时候也被成为对象定义,因为他们描述的是一类对象所具有的属性和方法。对象时某个特定引用类型的实例。新对象是使用new操作符后面跟一个构造函数来创建的。
一、Object类型
创建object实例的方式有两种。一种是使用new操作符后跟Object构造函数:
var person=new Object(); person.name="leo"; person.age=29;
另一种是用对象字面量表示法:
var person={ name:"leo", age:29 }
开发人员更青睐对象字面量语法,因为这种语法要求的代码量少,而且能够给人封装数据的感觉。
function displayInfo(args){ var output=""; if(typeof args.name=="string"){ output+="Name:"+args.name+"\n"; } if(typeof args.age=="number"){ output+="Age:"+ages.age+"\n"; } alert(output); } displayInfo({ name:"leo", age:29 }); dislayInfo({ name:"leo" });
一般来说,访问对象属性时都是用点表示法,不过,在javascript也可以使用方括号来访问对象的属性。
alert(person["name"]); alert(person.name);
二、Function类型
每个函数都是Funmtion类型的实例,而且都与其他引用类型一样具有属性和方法。由于函数是对象,因此函数名实际上也是一个指向函数对象的指针。
函数声明语法:
function sum(num1,num2){ return num1+num2; }
函数表达式语法:
var sum=function(num1,num2){ return num1+num2; }
2.1 函数没有重载
2.2 函数声明和函数表达式
解析器在向执行环境中加载数据时,对函数声明和函数表达式并非一视同仁。解析器会先读函数声明,并使其在执行任何代码之前可用(可以访问);至于函数表达式,则必须等到解析器执行到他所在的代码行,才会真正被解释执行。
alert(sum(10,10)); function sum(num1,num2){ return num1+num2; }
以上代码完全可以正常运行。但将函数声明改为函数表达式之后将报错。
alert(sum(10,10)); var sum=function(num1,num2){ //报错 return num1+num2; }
2.3 作为值的函数
因为ECMAScript中的函数名本身就是变量,所以函数也可以作为值来使用。也就是说,不仅可以像传递参数一样把一个函数传递给另一个函数,而且可以将函数作为另一个函数的结果返回。
function callSomeFunction(someFunction,someArgument){ return someFunction(someArgument); }
这个函数接受两个参数。第一个参数应该是一个函数,第二个参数应该是要传递给该函数的一个值。就可以像下面这样传递函数了:
function add10(num){ return num+10; } var result1=callSomeFunction(add10,10); alert(result1); //20
2.4 函数内部属性:arguments、this和caller
2.4.1 arguments对象
在函数内部,有两个特殊的对象:arguments和this。其中arguments的主要用途是保存函数参数,但这个对象还有一个名叫callee的属性,该函数是一个指针,指向拥有这个arguments对象的函数。
看下面阶乘函数:
function factorial(num){ if(num<=1){ return 1; }else{ return num*factorial(num-1) } }
定义阶乘函数一般都要用到递归算法。这个函数的的执行和函数名factorial紧紧耦合在一起。为了消除这种耦合,可以像下面使用arguments.callee
function factorial(num){ if(num<=1){ return 1; }else{ return num*arguments.callee(num-1) } }
在重写后的factorial()函数内没有再引用函数名factorial。这样无论引用函数时使用的是什么名字,都可以保证正常完成递归调用。例如:
var trueFactorial=factorial; factorial=function(){ return 0; } alert(trueFactorial(5)); //120 alert(factorial(5)); //0
在解除了函数体内的代码与函数名的耦合状态后,trueFactorial仍然能够正常的计算阶乘。
2.4.2 this对象:
window.color="red"; var o={color:"blue"}; function sayColor(){ alert(this.color); } sayColor(); //"red" o.sayColor=sayColor; o.sayColor(); //"blue"
2.4.3 Caller
这个属性中保存着调用当前函数的函数的引用,如果是在全局作用于中调用当前函数,他的值为null
function outer(){ inner(); } function inner(){ alert(inner.caller); } outer(); //function outer(){ inner();}
为了实现松散耦合,可以使用aurguments.callee.caller
function outer(){ inner(); } function inner(){ alert(arguments.callee.caller); //arguments.callee.caller } outer(); //function outer(){ inner();}
2.5 函数属性和方法
2.5.1 length属性
length属性表示函数希望接受的命名参数的个数
function sayName(name){ alert(name); } function sum(num1,num2){ return num1+num2; } function sayHi(){ alert("hi"); } alert(sayName.length); //1 alert(sum.length); //2 alert(sayHi.length); //0
2.5.2 prototype属性
2.5.3 apply方法
2.5.4 call方法
2.5.5 bind方法