js中的this都有哪些作用?
- 当函数作为对象的方法调用时,this 指向该对象
- 当函数作为单纯函数调用时,this 指向全局对象(严格模式时,为 undefined)
- 构造函数中的 this 指向新创建的对象
- 嵌套函数中的 this 不会继承上层函数的this,如果需要,可以用一个变量保存上层函数的 this。
在函数中this到底取何值,是在函数真正被调用执行的时候确定的,函数定义的时候确定不了。因为this的取值是执行上下文环境的一部分,每次调用函数,都会产生一个新的执行上下文环境。 如果在函数中使用了this,只有在该函数直接被某对象调用时,该this才指向该对象。
this的取值,分四种情况:
情况1:构造函数
1 | function Foo(){ |
以上代码中,如果函数作为构造函数用,那么其中的this就代表它即将new出来的对象。
注意,以上仅限new Foo()的情况,即Foo函数作为构造函数的情况。如果直接调用Foo函数,而不是new Foo(),情况就大不一样了:1
2
3
4
5
6
7
8function Foo1(){
this.name = "cchroot";
this.year = 1994;
console.log(this);//Window {top:Window, window:Window, location:Location, exter}
}
Foo1();
//这种情况下this是window
情况2:函数作为对象的一个属性
如果函数作为对象的一个属性时,并且作为对象的一个属性被调用时,函数中的this指向该对象。1
2
3
4
5
6
7
8var obj = {
x:10,
fn:function (){
console.log(this);//Object {x:10, fn:function}
console.log(this.x);//10
}
};
obj.fn();
以上代码中,fn不仅作为一个对象的一个属性,而且的确是作为对象的一个属性被调用。结果this就是obj对象。
注意,如果fn函数不作为obj的一个属性被调用,会是什么结果呢?1
2
3
4
5
6
7
8
9var obj = {
x:10,
fn:function (){
console.log(this);//Window {top:Window, window:Window, location:Location}
console.log(this.x);//undefined
}
};
var fn1 = obj.fn;
fn1();
如上代码,如果fn函数被赋值到了另一个变量中,并没有作为obj的一个属性被调用,那么this的值就是window,this.x为undefined。
情况3:函数用call或者apply调用
当一个函数被call和apply调用时,this的值就取传入的对象的值。至于call和apply如何使用,可以参见之前分享的:重温apply和call。1
2
3
4
5
6
7
8var lalala = {
x:10
};
var lalala1 = function(){
console.log(this); //Object {x:10}
console.log(this.x); // 10
}
lalala1.call(lalala);
情况4:全局 & 调用普通函数
在全局环境下,this永远是window,这个应该没有非议。1
console.log(this === window);//true
普通函数在调用时,其中的this也都是window。1
2
3
4
5
6var y = 10;
var yyy = function(){
console.log(this); //Window {top:Window, window:Window, location:Location}
console.log(this.x); // 10
}
yyy();
不过下面的情况你需要注意一下:1
2
3
4
5
6
7
8
9
10
11var specialobj = {
x: 10,
fn:function(){
function f(){
console.log(this);//Window {top:Window, window:Window, location:Location}
console.log(this.x);//undefined
}
f();
}
};
specialobj.fn();
函数f虽然是在obj.fn内部定义的,但是它仍然是一个普通的函数,this仍然指向window。
情况5:在构造函数的prototype中,this代表着什么?
1 | function z(){ |
如上代码,在Fn.prototype.getName函数中,this指向的是z1对象。因此可以通过this.name获取z1.name的值。
其实,不仅仅是构造函数的prototype,即便是在整个原型链中,this代表的也都是当前对象的值。
注:本文是当时查看王福朋前辈的博客:深入理解javascript原型和闭包 系列文字做的笔记,以及自己的一些理解、见解,以上如果有不理解的童鞋,可以访问前辈的文章链接进行查看。