重温——this

js中的this都有哪些作用?

  1. 当函数作为对象的方法调用时,this 指向该对象
  2. 当函数作为单纯函数调用时,this 指向全局对象(严格模式时,为 undefined)
  3. 构造函数中的 this 指向新创建的对象
  4. 嵌套函数中的 this 不会继承上层函数的this,如果需要,可以用一个变量保存上层函数的 this。

在函数中this到底取何值,是在函数真正被调用执行的时候确定的,函数定义的时候确定不了。因为this的取值是执行上下文环境的一部分,每次调用函数,都会产生一个新的执行上下文环境。 如果在函数中使用了this,只有在该函数直接被某对象调用时,该this才指向该对象。

this的取值,分四种情况:

情况1:构造函数

1
2
3
4
5
6
7
8
function Foo(){
this.name = "cchroot";
this.year = 1994;
console.log(this);//Foo {name:"cchroot", year:1994}
}
var f1 = new Foo();
console.log(f1.name);//cchroot
console.log(f1.year);//1994

以上代码中,如果函数作为构造函数用,那么其中的this就代表它即将new出来的对象。

注意,以上仅限new Foo()的情况,即Foo函数作为构造函数的情况。如果直接调用Foo函数,而不是new Foo(),情况就大不一样了:

1
2
3
4
5
6
7
8
function 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
8
var 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
9
var 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
8
var 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
6
var 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
11
var 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
2
3
4
5
6
7
8
9
function z(){
this.name = 'cchroot';
this.year = 1994;
}
z.prototype.getName = function() {
console.log(this.name);
}
var z1 = new z();
z1.getName(); //cchroot

如上代码,在Fn.prototype.getName函数中,this指向的是z1对象。因此可以通过this.name获取z1.name的值。

其实,不仅仅是构造函数的prototype,即便是在整个原型链中,this代表的也都是当前对象的值。




注:本文是当时查看王福朋前辈的博客:深入理解javascript原型和闭包 系列文字做的笔记,以及自己的一些理解、见解,以上如果有不理解的童鞋,可以访问前辈的文章链接进行查看。