JS中this的指向:this在面向对象编程中非常重要,它的值取决于调用的模式。在JS中一共有四种调用模式,方法调用模式、函数调用模式、构造器调用模式和apply调用模式。
方法调用模式:当一个函数被保存为对象的一个属性时,我们称它为一个方法。当方法被调用时,this被绑定到该对象。方法可以使用this去访问对象,所以它能从对象中取值或修改该对象。this到对象的绑定发生在调用的时候。通过this可取的它们所属对象的上下文的方法称为公共方法。
var myobj = { value: 1, inc: function (){ return this.value } } myobj.inc(); //输出1
函数调用模式:当一个函数并非一个对象的属性时,那么它被当作一个函数来调用。当一个函数被调用时,this被绑定到全局对象。这是语言设计上的一个错误,倘若语句设计正确,当内部函数被调用时,this应该仍然绑定到外部函数的this变量中。幸运的是,有一个很容易的解决方案,如果该方法定义一个变量并给它赋值为this,那么内部函数就可以通过变量访问到this。
var myobj = {value: 1} var value = 10; myobj.double = function (){ var that = this; var this01 = (function (){ return that.value; })(); var this02 = (function (){ return this.value; })(); console.log(this01); //this01输出1 console.log(this02); //this02输出10 } myobj.double()
构造器调用模式:如果在一个函数前面带上一个new来调用,那么将创建一个隐藏接到该函数的prototype成员的新对象,同时this将会被绑定到那个新对象上。new前缀也会改变return语句的行为。
//创建一个名为Quo的构造器函数 var Quo = function (string){ this.status = string } //给Quo的所有实例提供一个名为getStatus的公用方法 Quo.prototype.getStatus = function (){ return this.status } //构造一个Quo实例 var myQuo = new Quo('csh'); myQuo.getStatus(); //输出csh
结合new前缀调用的函数被称为构造器函数,按照约定,它们保存在以大写格式命名的变量里。如果调用构造函数时没有在前面加上new,可能会发生非常糟糕的事情。所以大写约定非常重要(不推荐使用构造器函数)。
apply调用模式:在JS里面函数是拥有方法的。apply方法让我们构建一个参数数组并用其去调用函数。它也允许我们选择this的值。apply方法接收两个参数。第一个是将被绑定给this的值,第二个就是一个参数数组。当apply第一个参数为空时,this默认调用全局对象。
var add = function (a, b){ return a + b; } var arr = [3, 4]; console.log(add.apply(null, arr)); //输出7 var myOBJ = {name: 'csh'}; var myname = function (){ return this.name; } console.log(myname.apply(myOBJ, null));//输出csh