JavaScript 中的 This

在Javascript中 This 指向 和 闭包是绕不开的问题, 今天我们来谈一下关于This  

主要是根据看《JavaScript 语言精粹》 和《you don't konw Js》 以及 一些博客文章 而总结的···

在《JavaScript 语言精粹》中说到,this 取决于调用的模式,它指向什么完全取决于函数在哪里被调用, 在JavaScript 中共有四种模式

 

1、方法调用模式 (隐式绑定)

   当时函数被作为一个对象的属性时,我们称它为一个方法,当时这个方法被调用时,this 被绑定到该对象。

 1   var myObject = {
 2       value :0,
 3       increment:function(inc) {
 4          this.value += typeof inc === 'number' ? inc :1;
 5      }
 6   }
 7   
 8   myObject.increment();
 9   console.log(myObjec.value);   //  1
10  
11  myObject .increment(3);
12  console.log(myObjec.value);  //4

对象属性引用链只有上一层或者说最后一层在调用位置上起作用

 1 function foo() {
 2     console.log(this.a);
 3 }
 4 
 5 var obj2 = {
 6     a: 42,
 7     foo:foo
 8 };
 9 
10 var obj1 = {
11     a: 2,
12     obj2: obj2
13 };
14 
15 obj1.obj2.foo();  //42

 

 

2、函数调用模式(默认绑定)

   当函数不是对象属性时,它就是被当做一个函数来调用的···

  在此模式下,this 绑定到全局对象即window上,如果在方法内部调用一个函数,此内部函数仍然符合此种模式···《语言精粹》里面认为这是一个bug,因为不能直接共享该方法对对象的访问权。不过也能容易解决这个问题,可以定义一个变量that 赋值为this.  在严格模式下,不能将全局对象用于默认绑定,this会绑定到undefined···

 1 //增加一个double方法
 2 myObject.double = function() {
 3     var that = this;
 4     var helper = function() {
 5         that.value = add(that.value,that.value);
 6     }
 7     helper();
 8 }
 9 
10 myObject.double();
11 console.log(myObject.value);  //6

此时对象中value=3,所以最终结果为6.

 

3、 构造器调用模式

  如果在一个函数前面带上new 来调用,背地里会创建一个连接到该函数的prototype 成员的新对象,同时this 会绑定到那个新对象上。

  

 1 //增加一个double方法
 2 myObject.double = function() {
 3     var that = this;
 4     var helper = function() {
 5         that.value = add(that.value,that.value);
 6     }
 7     helper();
 8 }
 9 
10 myObject.double();
11 console.log(myObject.value);
12 
13 var Quo = function(str) {
14     this.str = str;
15 }
16 
17 Quo.prototype.get_status = function() {
18     return this.status;
19 }
20 
21 var quo = new Quo("park");
22 conlose.log(que.get_status());  //park

   如果构造函数中有返回值且为一个对象,则this 会绑定到该对象上···如果返回为普通类型的值,则无影响··

 

四、Apply 调用模式 (显示绑定)

  函数也可以拥有方法,apply方法让我们构造一个函数数组传给调用函数,第1个是要绑定给this 的值,第2个是参数数组。

1 var statusObject = {
2     status:'A-OK';
3 };
4 
5 var status = Quo.prototype.get_status.apply(statusObject); //'A-OK'

statusObject 和 Quo 没有什么直接关系,但是可以利用apply调用它没有的 get_status方法,因为此时 this 已经绑定到 statusObject 上了。

 

    

posted @ 2017-04-23 21:55  wander的九号球  阅读(178)  评论(0编辑  收藏  举报