在JavaScript中this关键字的用法很灵活也很强大,但也往往给概念不清的初学者带来混淆,如果在一个function中你不知道this代表什么,那么你也很难理解这个function的作用了。
在JavaScript中this代表了当前执行的上下文,它是动态绑定的,也就是说只有到了function调用时才确定this所绑定的对象。所以我们只要清楚的了解到一个function是如何被调用的,我们也就能清楚的知道this绑定的是什么对象。在JavaScript中function一共有4种调用模式:
1.方法调用模式
当一个函数被保存为对象的一个属性时,这个函数就被成为方法。所以当一个方法被调用时,this就绑定到该对象:
var myObject = { value: 0, increment: function () { this.value += 1; } }; myObject.increment(); alert(myObject.value); //1 myObject.increment(); alert(myObject.value); //2
从上面的例子我们可以看到在myObject.increment()方法中,this绑定到myObject对象,并通过this去访问该对象的value属性。
2.函数调用模式
当一个函数并非一个对象的属性时(除了全局对象),那么它就被当作一个函数来调用,当函数以此模式来调用时,this将被绑定到全局对象。这很容易理解,但是需要注意的是,一个内部函数被调用时,this仍然是被绑定到全局对象,比如:
myObject.someMethod = function () { this.value = 2; return function () { alert(this.value); //undefined }; }; var method = myObject.someMethod(); method(); //undefined
我们可以看到,someMethod中在内部返回了一个匿名函数,在这个函数中this绑定的不是外部函数someMethod的this变量(即myObject),而是全局对象,因为我们没有定义全局变量value,所以显示的结果为undefined。如果我们需要将内部函数的this也绑定到myObject对象,我们可以这样做:
myObject.someMethod = function () { this.value = 2; var that = this; return function () { alert(that.value); //2 }; }; var method = myObject.someMethod(); method(); //2
3.构造器调用模式
所谓的构造器模式就是使用new关键字来调用一个函数,这样将创建一个隐藏链接到该函数的prototype成员的新对象,并且this关键字将会绑定到那个新对象上。
function Person() { this.age = 20; } var person = new Person(); alert(person.age); //20
当然,我们应当要注意:如果在调用Person()时,没有使用new关键字,this将会绑定到全局对象上,这样很可能会造成全局变量污染!!
4.Apply调用模式
因为JavaScript是一门函数式的语言(糅合了c语法),所以函数也是对象,可以拥有方法。
函数的apply方法让我们构建一个参数数组并用其去调用函数,它也允许我们选择this所绑定的值。apply方法接受两个参数,第一个参数是指定this所绑定的值,第二个就是参数数组:
function add(a, b) { return a + b; } var array = [3, 4]; var result = add.apply(null, array); //这里将add中的this指定为null alert(result);
另外,函数对象还有call方法与apply方法类似,只是将参数数组改为参数列表。
总结:我们只要搞清楚一个函数他是如何被调用的,就能清楚的知道this所绑定的值,这样就不容易混淆了