当箭头函数被普通函数包裹

作者: 小遁哥 | 来源:发表于2020-11-15 14:37 被阅读0次

    春暖花开,万物复苏,又到了看面试题的时候...

    很多文章讲述箭头函数this的指向,都提到了定义二字,是容易误导人的,MDN中这样解释

    箭头函数不会创建自己的this,它只会从自己的作用域链的上一层继承this。

        window.oop = 'window';
        let obj = {
          oop: 'obj',
          print: function () {
            setTimeout(function () {
              console.log(this.oop);
            });
          },
        };
        obj.print();
    

    此时会输出"window",普通函数的this是谁调用指向谁,setTimeout作为宏任务,是在在全局环境下执行的。

        window.oop = 'window';
        let obj = {
          oop: 'obj',
          print: function () {
            setTimeout(() => {
              console.log(this.oop);
            });
          },
        };
        obj.print();
    

    此时则会输出"obj",因为 obj.print使得print函数的this指向obj对象,被setTimeout里的箭头函数继承

        window.oop = 'window';
        let obj = {
          oop: 'obj',
          print: function () {
            setTimeout(() => {
              console.log(this.oop);
            });
          },
        };
        const print = obj.print;
        print();
    

    此时输出的是windowprint();是在全局环境下调用的,所以setTimeout里的箭头函数继承
    window


    React 为啥要绑定this
    在绑定事件函数时

    <button onClick={this.handleClick} >
    </button>
    

    其实类似于(严格模式)

    const print = obj.print;
    print();
    

    下面的例子解释了为什么箭头函数解决了this的指向问题


        window.oop = 'window';
        let obj = {
          oop: 'obj',
          print: () => {
            setTimeout(() => {
              console.log(this.oop);
            });
          },
        };
        obj.print();
    

    输出"window",尽管通过obj.print(),但是此时print中的this是继承上一层的

    箭头函数的出现是为了替普通函数分忧的,不是替代,MDN解释如下

    箭头函数表达式的语法比函数表达式更简洁,并且没有自己的this,arguments,super或new.target。
    箭头函数表达式更适用于那些本来需要匿名函数的地方,并且它不能用作构造函数。

    看一个防抖的例子

    function debounce(func, delay) {
          let isFirstTime = true;
          let timer;
          return function (...args) {
            if (isFirstTime) {
              func.apply(this, args);
              isFirstTime = false;
            } else {
              clearTimeout(timer);
              timer = window.setTimeout(() => {
                func.apply(this, args);
              }, delay);
            }
          };
        }
        function sayHi() {
          console.log(this);
        }
        const oopBtn = document.getElementById('oop');
        oopBtn.addEventListener('click', debounce(sayHi, 500));
    

    如果将return返回的写成箭头函数,sayHithis将指向window

    相关文章

      网友评论

        本文标题:当箭头函数被普通函数包裹

        本文链接:https://www.haomeiwen.com/subject/uhynbktx.html