说道 JavaScript 高大上的技巧,this 关键字莫过之一了,而且 this 的使用频率相当高。不同与 Java 中 this 的三种用法,JavaScript 的 this 明确说只有一种用法,那就是 指向调用函数的对象 。下面分三种情况讨论:
作为对象方法调用
var obj = {
x: 0,
foo: function(x) {
this.x = x;
}
};
obj.foo(10);
console.log(obj.x); //10
这一种情况, this 绑定了调用函数的 obj 对象
作为函数调用
这种情况其实和第一种情况类似,请看:
var x = 0;
function foo(x) {
this.x = x;
}
foo(10);
console.log(this.x); //10
这里的 this 指向了全局 window , 类比第一种情况,可以写成这样(假设可以):
var window = {
x: 0,
foo: function(x) {
this.x = x;
}
};
window.foo(x);
console.log(this.x); //10
呵呵~~看出个所以然了吧,这不就是把全局 window 当做 this 绑定的对象嘛!
还有一种特例就是,对象函数的内部函数会丢失当前对象 this 的引用,请看:
var obj = {
x: 0,
foo: function(x) {
var boo = function(x) {
this.x = x;
};
boo(x);
}
};
obj.foo(10);
console.log(obj.x); //0
console.log(this.x); //10
明显,boo 函数的 this 指向了全局 window , x 的值并没有因此改变。遇到这种情况,可以这样解决:
var obj = {
x: 0,
foo: function(x) {
var that = this; //保存当前this引用
var boo = function(x) {
that.x = x;
};
boo(x);
}
};
obj.foo(10);
console.log(obj.x); //10
这里用一个 that 变量保存了 this 引用,以致于 that 指向当前对象。
作为构造函数调用
function Foo(x) {
this.x = x;
}
var foo1 = new Foo(10);
console.log(foo.x); //10
当构造函数被实例化时,this 自动指向实例化对象。
总结以上三种情况,都归结于一句话:this 指向调用函数的对象。
apply() 和 call()
最后,说一下 JavaScritp 提供的改变 this 绑定的方法 apply() 和 call() 。这两个方法都接收两个参数:要应用的对象和传入的参数,它们唯一的区别是 apply() 的参数传入一个数组,call() 只能一个一个的传入参数。知其一必知其二,下面我们拿 apply() 说事:
var obj = {
x: 10,
y: 10
};
var foo = function() {
return this.x - this.y;
};
console.log(foo.apply(obj)); //0
函数 Foo 绑定了对象 obj ,于是 this 指向 obj ,这是 apply() 最简单的用法。
apply() 还有一个很有用的用法,说明一下:
var array = [1, 2, 3, 4, 5];
console.log(Math.max.apply(null, array)); //5
console.log(Math.min.apply(null, array)); //1
数组被传入 Math.max() 和 Math.min() 方法中,第一个参数置空,表示没有对象调用。它们返回了数组的最大值和最小值