函数的四种调用模式
方法调用
当函数作为一个对象的属性时,被称为方法,当方法被调用时,this被绑定到该对象。方法可以通过this访问对象,this到对象的绑定发生在调用时。 函数调用 当一个函数并非一个对象的属性时,被作为函数调用。这时,this被绑定到全局对象。因此,内部函数无法通过this访问外部对象。 可以通过var that =this;在通过that访问外部对象。
构造器调用
使用new来调用,将会创建一新对象,并且将其链接到该函数的prototype上,同时this会绑定在新对象上。
Apply调用
可以使用函数提供的apply方法进行对函数的调用,这种方式可以将this绑定任意对象上。
闭包
函数访问被创建时所处的上下文,通过这种方式可以持久化局部变量,可以实现对变量访问的控制。 如下代码实现一个简单的闭包,使status常驻内存,并且保证只能通过getStatus获取值以及inc方法修改该值。
var o= function (status) {
return{
getStatus:function(){
return status;
},
inc:function(){
return ++status;
}
};
}(1)
下面的例子可以很好的理解内部函数能访问外部函数的实际变量而不是副本。
var a={}; var b={}; var c={}; var arr=[a,b,c]; var fun= function (arr) { var i; for(i=0;i<arr.length;i++){ arr[i].fun=function(i){ return function(){ alert(i); }; }(i); } } fun(arr); arr[0].fun(); arr[1].fun(); arr[2].fun();
下面的例子演示如何利用闭包产生安全的对象
var marker= function () {
var prefix='';
var seq=0;
return {
setPrefix: function (p) {
prefix=String(p);
},
setSeq: function (s) {
seq=s;
},
gen: function () {
var result=prefix+seq;
seq+=1;
return result;
}
}
}();
marker.setPrefix('p');
marker.setSeq(100);
console.log(marker.gen());
上面例子用来生成唯一的序列,只能通过setPrefix设置前缀,setSeq设置序号以及gen方法生成序列。无法通过任何其他方式修改内部的prefix和seq的值。