JavaScript 中的 this
Pin Young Lv9
  • content
    {:toc}

本文为慕课网 JavaScript深入浅出 JavaScript 中的 this笔记。

全局的 this

全局 this 一般指向全局对象,浏览器中的全局对象就是 window

例如:

1
2
3
4
5
console.log(this.document === document); //true
console.log(this === window); //true

this.a = 91;
console.log(window.a); //91

一般函数的 this

1
2
3
4
function f1 () {
return this;
}
console.log(f1() === window);//true, global object

可以看到一般函数的 this 也指向 window,在 nodeJS 中为 global object

1
2
3
4
5
function f2 () {
"use strict";//使用严格模式
return this;
}
console.log(f1() === undefined);//true

严格模式中,函数的 this 为 undefined

作为对象方法的函数的 this

1
2
3
4
5
6
7
var o = {
prop: 37,
f: function() {
return this.prop;
}
};
console.log(o.f()); // 37

上述代码通过字面量创建对象 o。

f 为对象 o 的方法。这个方法的 this 指向这个对象,在这里即对象 o。

1
2
3
4
5
6
7
8
9
var o = {
prop: 37
};

function independent() {
return this.prop;
}
o.f = independent;
console.log(o.f()); // 37

上面的代码,创建了对象 o,但是没有给对象 o,添加方法。而是通过 o.f = independent 临时添加了方法属性。这样这个方法中的 this 同样也指向这个对象 o。

对象原型链上的 this

1
2
3
4
5
6
7
8
9
var o = {
f: function() {
return this.a + this.b;
}
};
var p = Object.create(o);
p.a = 1;
p.b = 2;
console.log(p.f()); //3

通过 var p = Object.create(o) 创建的对象,p 是基于原型 o 创建出的对象。

p 的原型是 o,调用 f() 的时候是调用了 o 上的方法 f(),这里面的 this 是可以指向当前对象的,即对象 p。

get/set 方法与 this

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
function modulus() {
return Math.sqrt(this.re * this.re + this.im * this.im);
}
var o = {
re: 1,
im: -1,
get phase() {
return Math.atan2(this.im, this.re);
}
};
Object.defineProperty(o, 'modulus', {
get: modulus,
enumerable: true,
configurable: true
});
console.log(o.phase, o.modulus); // -0.78 1.4142

get/set 方法中的 this 也会指向 get/set 方法所在的对象的。

构造器中的 this

1
2
3
4
5
function MyClass() {
this.a = 25;
}
var o = new MyClass();
console.log(o.a); //25

new MyClass() 的时候,MyClass()中的 this 会指向一个空对象,这个对象的原型会指向 MyClass.prototype。MyClass()没有返回值或者返回为基本类型时,默认将 this 返回。

1
2
3
4
5
6
7
8
9
function C2() {
this.a = 26;
return {
a: 24
};
}

o = new C2();
console.log(o.a); //24

因为返回了对象,将这个对象作为返回值

call/apply 方法与 this

1
2
3
4
5
6
7
8
9
10
11
12
13
function add(c, d) {
return this.a + this.b + c + d;
}
var o = {
a: 1,
b: 3
};
add.call(o, 5, 7); // 1 + 3 + 5 + 7 = 16
add.apply(o, [10, 20]); // 1 + 3 + 10 + 20 = 34
function bar() {
console.log(Object.prototype.toString.call(this));
}
bar.call(7); // "[object Number]"

bind 方法与 this

1
2
3
4
5
6
7
8
9
10
11
12
13
function f() {
return this.a;
}
var g = f.bind({
a: "test"
});
console.log(g()); // test
var o = {
a: 37,
f: f,
g: g
};
console.log(o.f(), o.g()); // 37, test

绑定之后再调用时,仍然会按绑定时的内容走,所以 o.g() 结果是 test