this关键字引用的是包含它的函数作为某个对象的方法被调用时的那个对象。———《JavaScript.Dom高级程序设计》
这句话拆开来看
- this
- 包含this的函数
- 函数被调用时
-
以函数作为方法的对象
就是说,当函数被调用时,这个函数属于某个对象的方法,这个对象就是函数内部this关键字所指向的对象。
首先我们要了解的是,在JavaScript代码中,所有的变量和方法都包含在名为window的全局对象中。来看个简单的例子:
function showThis() {
alert(this); //window
}
showThis();
再来看一个例子:
var other = {
"showThis": function() {
console.log(this); // object other
}
};
other.showThis();
this指向了other对象。 因为showThis()函数在执行时, 它是属于other对象的方法被调用的, 所以这里的this指向了other对象。
再来看下面的例子:
var other = {
"showThis" : function(){
console.log(this);
}
};
function doit(fn) {
fn();
}
doit(other.showThis);
来猜猜 this指向了那里呢?
没错,是window对象。
和变量不同,关键字this没有作用域的限制,嵌套的函数不会从调用它的函数中继承this。 如果嵌套函数作为方法调用,其this值指向调用它的对象。 如果嵌套函数作为函数调用,其this值不是全局对象(非严格模式下)就是undefined(严格模式下)。———— 《JavaScript权威指南》
在这里,我们把other的属性方法showThis()作为参数传递给了doit()函数, 在JavaScript中参数是按值传递的,在fn()执行时,它不再作为other对象的方法,所以这里this关键字指向了window
如果想访问外部函数的this值,可以将this的值保存在一个变量里。
var other = {
"say" : function(){
alert("hello world");
},
"bind":function(){
document.onclick = function(){
this.say(); //出错
}
}
};
other.bind();
上面的代码会出错,因为onclick事件处理程序是作为DOM元素的方法的,this关键字指向了document。 稍微改一下:
var other = {
"say" : function(){
alert("hello world");
},
"bind":function(){
var self = this;
document.onclick = function(){
self.say(); //"hello world"
}
}
};
other.bind();
在bind()里将this关键字存至self变量, bind()的内部函数就可以通过self访问this。
DOM0级方法(onclick等)指定的事件处理程序,和DOM2级处理程序(addEventListener())指定的事件处理程序,都是作为DOM元素的方法的,this关键字指向了元素本身。但是在IE中使用attachEvent()方法添加的事件程序中,事件处理程序会在全局作用域中运行,this指向window。关于事件处理程序可以点击这里查看详解
个人小结
当函数作为某个对象的方法调用时,内部this关键字指向了该对象,如果不属于任何对象,this指向window。