JavaScript中,对this的简单记忆

JavaScript中的this一直是个大坑,现在,总结的this的一些规律(革命尚未成功,同志仍需努力奋斗):

直接调用的都是window
除非是bind绑定过的,其他情况下,直接调用的方法的this都是window。所谓的直接调用,就是直接以method()的形式调用,没有call, apply, new
看几种情况:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
function foo(){
    return this ;
}
foo(); // window
var obj = {
   foo: function (){ return this ; }
}
var foo = obj.foo;
foo(); // window
function Foo(){
   this .foo = function (){
     console.log( this );
   }
   var foo = this .foo;
   foo(); // window
}
new Foo();
 
 
谁调用,谁是 this
除非是bind绑定过的,一般情况下,谁调用这个方法,那么内部的 this 就指向这个对象。也就是说obj.method(),那么就指向obj。obj.foo.method(),那么就指向obj.foo
 
看几个例子:
var obj = {
   foo: function (){ return this ; }
}
obj.foo(); // obj调用,所以结果是obj
function foo(){ return this };
var obj = {};
obj.foo = foo;
obj.foo(); // obj调用,所以结果是obj
var obj = {
   bar: function (){ return this ; },
   foo: function (){
     return this .bar();
   }
}
obj.foo(); // 在foo中, this是obj, 而this调用的bar, 所以返回的是obj
var obj = {
    bar: {
      foo: function (){ return this }
    }
}
obj.bar.foo(); // obj.bar调用的foo,所以返回的结果是bar
function foo(){
   this .bar = function (){ return this }
   return this .bar();
}
foo(); // 由于foo中的this是window, 所以this.bar()返回的是window
function Foo(){
   this .foo = function (){ console.log( this ); }
   this .foo();
}
 
var object = new Foo(); // 由于this.foo中的this是object,所以this是object


new会生成一个新的this
所有情况下,(箭头函数不能使用new关键字),使用了new以后,会把内部的this指向新生成的对象。
除去bind的情况下,prototype中的this也指向新生成的对象

1
2
3
4
5
6
7
8
9
10
11
12
13
function Foo(){
   console.log( this ); // this指向新生成的对象,object
}
var object = new Foo();
function Foo(){
   this .foo = function (){ return this === object; }
}
var object = new Foo();
object.foo(); // 输出true
function Foo(){}
Foo.prototype.foo = function (){ return this === object; }
var object = new Foo();
object.foo(); // 输出true


call, apply是谁,this就是谁
除非是bind的情况,call, apply是谁,那么内部的this就是谁。


注意:如果是基本类型,那么javascript会把基本类型转换成Object的形式
也是看例子:

1
2
3
4
5
6
7
8
9
10
11
12
13
function foo(){ return this ; }
foo.call( "a" ); // String
typeof foo.call( "a" ); // object
var obj = {
   foo : function (){ return this ; }
}
obj.foo.call(1); // Number
typeof obj.foo.call(1); // object
function Foo(){
   this .foo = function (){ return this ; }
}
var object = new Foo();
object.foo.call(1); // Number


bind是谁,this就是谁
除了new这一种特殊情况,bind的对象是谁,那么this也就是谁。即使call, apply也没有权利改变。
注意:如果是基本类型,那么javascript会把基本类型转换成Object的形式

1
2
3
4
5
6
7
8
9
10
11
function foo() { return this ; }
foo = foo.bind(1);
foo(); // Number
typeof foo(); // object
function foo() { return this ; }
foo = foo.bind(1);
foo.call( "a" ); // Number 1
function Foo() { return this ; }
Foo.prototype.foo = ( function (){ return this ; }).bind(1);
var object = new Foo();
object.foo(); // Number


特殊情况
new这个关键词可以改变方法内部的this,使他指向新生成的对象

1
2
3
4
function Foo(){ this .foo = function (){ console.log( this === obj) } }
Foo = Foo.bind(1);
var obj = new Foo();
obj.foo(); // 输入true


箭头函数
箭头函数的this是根据定义环境的this来定的,也就是说定义的函数周围的this是什么,它的this就是什么。
而且不会被bind, call, apply所改变

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
var foo = ()=>{ return this };
foo() // window
var obj = { foo: ()=> this }
obj.foo(); // 由于定义的时候,周围的环境是window,所以返回window
var obj = {
   foo(){
      var bar= ()=>{ return this };
      return bar();
   }
}
obj.foo(); // 由于定义bar的时候,周围环境是obj,所以返回obj
var foo = obj.foo;
foo(); // 同理,这里是window
var foo = ()=>{ return this };
foo = foo.bind(1);
foo(); // window
foo.call(1); // window
foo.apply(1); // window
function Foo(){
   // 箭头函数
   var a = ()=>{
     console.log( this === object); // true
   }
   // 对比普通函数
   var b = function (){
     console.log( this === window); // true
   }
   
   this .foo = function (){
     a(); b();
   }
}
var object = new Foo();
object.foo();
function Foo(){}
// window
Foo.prototype.foo = ()=>{ return this }
// window
var object = new Foo();

object.foo(); // 由于定义foo的时候,周围环境是window,所以这里是window
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值