关于this经常有些爱混淆,现就此总结下,便于以后查阅。
主要参考自 1.王福朋的博客:我比较喜欢他写博客的风格。
http://www.cnblogs.com/wangfupeng1988/p/3988422.html
2.阮一峰大大的博客:
http://www.ruanyifeng.com/blog/2010/04/using_this_keyword_in_javascript.html
this是Javascript语言的一个关键字。
它代表函数运行时,自动生成的一个内部对象,只能在函数内部使用。随着函数使用场合的不同,this的值会发生变化。但是有一个总的原则,那就是this指的是,调用函数的那个对象。——这句话很精髓。
function test1(){
var a = "哈哈";
console.log(this.a); //undefined
console.log(this); //Window
}
test1();
这里比较好说明,undefined出现的原因,就是this指向的是window对象。他就是在window中被调用。
var testobj = {
name:"jerry",
fn:function(){
console.log(this.name); //jerry
}
}
testobj.fn();
testobj的时候对fn()进行了调用,所以,这时的this是这个testobj对象。
这前面这样解释,确实没什么问题,且对大部分场合都试用,但在部分情境下,这里this又不受用了。
我就在调用testobj前面加个window. ,这里依然没有影响结果。所以这里的调用对象又要变通下,不是最终的window,而是testobj这一级对象。就此,我又去查了一番,现部分总结在下面:(不对,请指正!)
情况1:如果this没有被上一级的对象所调用,那么this指向的就是window。
情况2:如果this有被上一级的对象所调用,那么this指向的就是上一级的对象。那就是上个例子的testobj对象。
情况3:如果this所在的函数包含多个对象,尽管这个函数是被最外层的对象所调用,this指向的也只是它上一级的对象。
var testobj = {
a:1,
b:{
a:12,
fn:function(){
console.log(this.a); //12
}
}
}
testobj.b.fn();
和这个比较:
var testobj = {
a:1,
b:{
a:12,
fn:function(){
console.log(this.a); //undefined
console.log(this); //window
}
}
}
var f = testobj.b.fn;
f();
这是一个赋值定义,调用函数的问题。这就要弄懂,什么时候this被谁调用的问题。后面的例子虽然函数fn是被对象b所引用,但是在将fn赋值给变量j的时候并没有执行所以其指向的是window。前者是直接调用,所以两者不同,this.a也就不一样。
还有就是前面两位大神都讲过的,构造函数的this。我们来看看:
function Foo(){
this.content = "构造函数";
console.log(this);//Foo
}
var obj = new Foo();
console.log(obj.content); //"构造函数"
再看看这个,
function Foo(){
this.content = "构造函数";
console.log(this);//window
}
Foo();
console.log(this.content); //"构造函数"
这里主要就是看其构造函数有没有new对象出来,有的话,那this指向这个对象,没有,就作为普通函数调用,其指向全局window。
王大大也在第四点讲到了这一点。其中,这个例子有点难以理解,
var testobj = {
a:1,
fn:function(){
function f(){
console.log(this.a); //undefined
console.log(this); //window
}
f();
}
}
testobj.fn();
开始还是有些许不明白,最后其实溯其本源看的话,f()就作为普通函数调用,所以还是指向window,那this.a也就取不到值了。
最后一种情况,call()和apply()、bind()会改变this指向。上代码:
var testobj = {
content:"jerry",
fn:function(){
console.log(this.content); //jerry
}
}
var b = testobj.fn;
b.call(testobj);
也就是说,this就会指向那个对象。apply()和call()类似,只是后面传的值是数组。
bind()和以上都有所不同,主要是它的返回值不一样,它返回的是函数。
var testobj = {
content:"jerry",
fn:function(){
console.log(this.content); //jerry
}
}
var f = testobj.fn;
var a = f.bind(testobj);
a(); //执行a()后,才会打印。
目前就总结出了,这么多,以后要是还有其他的,我再补充。