zoukankan      html  css  js  c++  java
  • 箭头函数中的this

    普通函数中的this:

    1.this总是代表它的直接调用者, 例如 obj.func ,那么func中的this就是obj
    2.在默认情况(非严格模式下,未使用 'use strict'),没找到直接调用者,则this指的是 window
    3.在严格模式下,没有直接调用者的函数中的this是 undefined
    4.使用call,apply,bind(ES5新增)绑定的,this指的是 绑定的对象

    首先了解一下作用域链:

    当在函数中使用一个变量的时候,首先在本函数内部查找该变量,如果找不到则找其父级函数,

    最后直到window,全局变量默认挂载在window对象下

    箭头函数有几个使用注意点。

    (1)函数体内的this对象,就是定义时所在的对象,而不是使用时所在的对象。

    (2)不可以当作构造函数,也就是说,不可以使用new命令,否则会抛出一个错误。

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

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

    上面四点中,第一点尤其值得注意。this对象的指向是可变的,但是在箭头函数中,它是固定的。

    箭头函数中的this

    默认指向在定义它时,它所处的对象,而不是执行时的对象, 定义它的时候,可能环境是window

    1.全局变量默认挂载在window对象下

    <script>
      var aa = 2;
      alert(window.aa);
      (function () {
        aa = 3;
      })();
      console.log(window.aa);
    </script>
    

    2.在普通函数中,this指向它的直接调用者;如果找不到直接调用者,则是window

    示例1:

    <script>
      function test() {
        console.log(this);
      }
      test();
    </script>
    

    结果是: window
    原因: test()是一个全局函数,也就是说是挂在window对象下的,所以 test()等价于 window.test() ,所以此时的this是window
    示例2:

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

    结果是: window
    匿名函数,定时器中的函数,由于没有默认的宿主对象,所以默认this指向window

    问题: 如果想要在setTimeout中使用这个对象的引用呢?

    用一个 变量提前把正确的 this引用保存 起来, 我们通常使用that = this, 或者 _this = this来保存我们需要的this指针!

    <script>
      var obj = {
        func: function() {},
        say: function () {
          var that = this;   //此时的this就是obj对象
          setTimeout(function () {
            console.log(this)
            that.func()
          });
        }
      }
      obj.say();
    </script>
    

    示例3:

    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
    val变量在没有指定对象前缀,默认从函数中找,找不到则从window中找全局变量

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

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

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

    第二次调用的时候, this指的是window, val指的是window.val

    第二次的结果受第一次的影响

    3.在严格模式下的this

    <script>
      function test() {
        'use strict';
        console.log(this);
      }
      test();
    </script>
    

    结果是: undefined

    4.箭头函数中的 this

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

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

    示例(多层嵌套的箭头函数):

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

    因为f1定义时所处的函数 中的 this是指的 obj所以不管有多层嵌套,都是 obj

    示例(复杂情况: 普通函数和箭头函数混杂嵌套)

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

    结果: 都是 window,因为 箭头函数在定义的时候它所处的环境相当于是window所以在箭头函数内部的this函数window

    示例(严格模式下的混杂嵌套)

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

    结果都是undefined

    说明: 严格模式下,没有宿主调用的函数中的this是undefined!!!所以箭头函数中的也是undefined!

    总结:

    使用箭头函数,可以让我们解决一些在匿名函数中 this指向不正确的问题;但是要注意在和普通函数混合的时候,this的指向可能是window !

  • 相关阅读:
    Good Bye 2014 B. New Year Permutation(floyd )
    hdu 5147 Sequence II (树状数组 求逆序数)
    POJ 1696 Space Ant (极角排序)
    POJ 2398 Toy Storage (叉积判断点和线段的关系)
    hdu 2897 邂逅明下 (简单巴什博弈)
    poj 1410 Intersection (判断线段与矩形相交 判线段相交)
    HDU 3400 Line belt (三分嵌套)
    Codeforces Round #279 (Div. 2) C. Hacking Cypher (大数取余)
    Codeforces Round #179 (Div. 2) B. Yaroslav and Two Strings (容斥原理)
    hdu 1576 A/B (求逆元)
  • 原文地址:https://www.cnblogs.com/laijun/p/7402135.html
Copyright © 2011-2022 走看看