方法调用模式:
当一个函数被保存为对象的一个属性时,我们称它为一个方法。当一个方法被调用时,this被绑定到该对象。
//方法调用模式 var myObject = { value: 0 , increment: function(inc){ this.value += (typeof inc === 'number') ? inc :1; } }; myObject.increment(); document.writeln(myObject.value); myObject.increment(2); document.writeln(myObject.value);
函数调用模式:
当一个函数非一个对象的属性时,那么它被当作一个函数来调用。当函数以此模式调用时,this被绑定到全局对象。这是语言设计上的一个错误。若语言设计正确,当内部函数被调用时,this应该仍然绑定到外部函数的this变量。解决方法是:如果 该方法定义一个变量并给它赋值为this,那个内部函数就可以通过那个变量访问到this。按约定,给那个变量命名为that。
//函数调用模式 function add(a,b){ return a+b; } myObject.doubled = function () { var that = this; document.writeln(that.value); var helper = function () { that.value = add(that.value,that.value); } helper(); }; myObject.doubled(); document.writeln(myObject.value);
构造器调用模式:
javascript是一门基于原型继承的语言。是无类别的。如果在一个函数前面带上new来调用,那么将创建一个隐藏连接到该函数的prototype成员的新对象,同时this将会被绑定到那个新对象上。同时new前缀也会改变return语句的行为,这里就不做更多说明了。
//构造器调用模式 var Quo = function (string){ this.status = string; } Quo.prototype.get_status = function(){ return this.status; }; //构造一个Quo实例 var myQuo = new Quo("confused"); document.writeln(myQuo.get_status());
Apply调用模式:
因为javascript是一门函数式的面向对象语言,所以函数可以拥有方法。apply方法让我们构建一个参数数组并用其去调用函数。它也允许我们选择this的值。apply接收两个参数。第一个将被绑定给this的值。第二登上就是一个参数数组。
//Apply调用模式 var statusObject = { status:'A-OK' }; //statusObject 并没有继承自Quo.prototype,但我们可以在statusObject上调用 //用get_status 方法,尽管statusObject并没有一个名为get_status的方法。 var status = Quo.prototype.get_status.apply(statusObject); document.writeln(status); //不会改变原来的属性 document.writeln(myQuo.get_status());
总结:
javascript的this非常灵活也非常危险,开发者在使用this的时候,要清楚的知道this所指向的是哪个对象,如果明确了接下来要大量使用指向某个对象的this,最好的做法是将this赋值于类似that的这种变量,以免在下面使用子函数的时候混淆。