本文为慕课网 JavaScript深入浅出 JavaScript 中的 this笔记。
全局的 this 全局 this 一般指向全局对象,浏览器中的全局对象就是 window
。
例如:
1 2 3 4 5 console .log(this .document === document ); console .log(this === window ); this .a = 91 ;console .log(window .a);
一般函数的 this 1 2 3 4 function f1 ( ) { return this ; } console .log(f1() === window );
可以看到一般函数的 this 也指向 window,在 nodeJS 中为 global object
1 2 3 4 5 function f2 ( ) { "use strict" ; return this ; } console .log(f1() === undefined );
严格模式中,函数的 this 为 undefined
作为对象方法的函数的 this 1 2 3 4 5 6 7 var o = { prop: 37 , f: function ( ) { return this .prop; } }; console .log(o.f());
上述代码通过字面量创建对象 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());
上面的代码,创建了对象 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());
通过 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);
get/set 方法中的 this 也会指向 get/set 方法所在的对象的。
构造器中的 this 1 2 3 4 5 function MyClass ( ) { this .a = 25 ; } var o = new MyClass();console .log(o.a);
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);
因为返回了对象,将这个对象作为返回值
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 ); add.apply(o, [10 , 20 ]); function bar ( ) { console .log(Object .prototype.toString.call(this )); } bar.call(7 );
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()); var o = { a: 37 , f: f, g: g }; console .log(o.f(), o.g());
绑定之后再调用时,仍然会按绑定时的内容走,所以 o.g() 结果是 test