ES6之箭头函数中的this

    在讲箭头函数中的this之前我们先介绍一下普通函数中的this。    

    普通函数中的this:

(1)this指向它的直接调用者

(2)默认的,非严格模式下,没找到直接调用者则指向window

(3)严格模式下,没直接调用者的this是undefined

(4)使用call,apply,bind绑定对象,则this指向被绑定的对象。

ES5中
window.val = 1;
  var obj = {
    val: 2,
    dbl: function () {
      this.val *= 2;
      val *= 2;
      console.log(val);
      console.log(this.val);
    }
  };

  obj.dbl();
  var func = obj.dbl;
  func();
// 输出结果
2 4 8 8

分析:(1) 12行代码调用

val变量在没有指定对象前缀,默认从函数中找,找不到则从window中找全局变量

即 val *=2 就是 window.val *= 2

this.val默认指的是 obj.val ;因为 dbl()第一次被obj直接调用

(2)14行代码调用

func() 没有任何前缀,类似于全局函数,即  window.func调用,所以

第二次调用的时候, this指的是window, val指的是window.val。第二次的结果受第一次的影响。

作用域链

      当在函数中使用一个变量的时候,首先在本函数内部查找该变量,如果找不到则找其父级函数,最后直到window,全局变量默认挂载在window对象下。

箭头函数中的this

 

箭头函数中的this特性

(1)箭头函数中的this对象就是定义时所在的对象,而不是使用时所在的对象

(2)不可以使用new命令创建实例

(3)不可以使用argument对象,该对象在函数体内不存在。如果要用,可以用reset参数代替

(4)不可以使用yield命令,因此箭头函数不能用作Generator函数。

(5)由于箭头函数没有自己的this,所以当然也就不能用call()、apply()、bind()这些方法去改变this的指向。

示例:

  var obj = {
    say: function () {
      setTimeout(() => {
        console.log(this)
      });
    }
  }
  obj.say(); 

    输出:

 obj

    此时的 this指的是定义它的对象, obj,而不是 window。

多层嵌套的箭头函数:

var obj = {
    say: function () {
      var f1 = () => {
        console.log(this); // obj
        setTimeout(() => {
          console.log(this); // obj
        })
      }
      f1();
    }
  }
undefined
 obj.say()

    输出:

Object
Object 

    由于fa定义时所处的函数中的this是指向obj的,所以无论嵌套多少层都指向obj。

箭头函数与函数比较:

function Timer() {
  this.s1 = 0;
  this.s2 = 0;
  // 箭头函数
  setInterval(() => this.s1++, 1000);
  // 普通函数
  setInterval(function () {
    this.s2++;
  }, 1000);
}
var timer = new Timer();
setTimeout(() => console.log('s1: ', timer.s1), 3100);
setTimeout(() => console.log('s2: ', timer.s2), 3100);

    输出:

 s1: 3
 s2: 0

   Timer函数内设置了2个定时器,第一个是箭头函数,其this是指向定义它的函数Timer,所以调用timer.s1会被更细3次。第二个是普通函数,其this是指向运行时所在函数的作用域。

普通函数和箭头函数混杂嵌套:

var obj = {
    say: function () {
      var f1 = function () {
        console.log(this);    // window, f1调用时,没有宿主对象,默认是window
        setTimeout(() => {
          console.log(this); // window
        })
      };
      f1();
    }
  }
  obj.say()
输出
Window 
Window

因为 箭头函数所在的函数位置为f1,f1中的this是指向window,所以箭头函数的this与指向window。

箭头函数中使用call()、apply()、bind():

(function() {
  return [
    (() => this.x).bind({ x: 'inner' })()
  ];
}).call({ x: 'outer' });

输出:

["outer"]

由于箭头函数没有自己的this,所以使用bind()方法无法改变this的指向。

     总结:箭头函数中的this指向是固定的,并不是因为箭头函数内部有绑定this的机制,实际原因是箭头函数内部没有this,导致内部的this就是外层代码块的this。正因为它没有this,所以也就不能用作构造函数。

posted on 2017-06-22 18:07  公子小苏  阅读(569)  评论(0编辑  收藏  举报