zoukankan      html  css  js  c++  java
  • 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,所以也就不能用作构造函数。

  • 相关阅读:
    单表查询
    多表查询
    (Redis基础教程之七)如何使用Redis中的Hashes
    (Python基础教程之三)Python代码中添加注释
    (Python基础教程之二)在Sublime Editor中配置Python环境
    (Redis基础教程之六)如何使用Redis中的List
    (Redis基础教程之五)如何在Redis中操作字符串
    (Redis基础教程之一)如何在Ubuntu 18.04上安装和保护Redis
    Redis数据类型简介(十分钟快速学习Redis)
    如何使用,操作Redis数据库
  • 原文地址:https://www.cnblogs.com/microcosm/p/7066451.html
Copyright © 2011-2022 走看看