zoukankan      html  css  js  c++  java
  • ES6与React中this完全解惑

    计划写很长的篇幅,预计12月初完成。

       这篇文章涉及的知识较多,可能一次消化不了,可以渐渐来。

      先说结论:

      无论是ES6还是React的this,相对于ES5,只是增加了箭头函数this绑定了其封闭上下文,自己实现了该词法,其它的关于this的与ES5仍然一样。

      目录:    

      1.ES5中对this使用的4种方式
      2.ES6中箭头函数中的this
      3.ES6中class中的this
      4.React中组件里的this 组件里事件函数,其实相当于把对象方法赋值给新变量后再调用,这和ES5中是一样的,变成了函数调用,this指向全局。

      要理解ES6的this知识,首先必须非常熟悉ES5里this的知识,要不然还是会一头雾水。

      1.ES5中对this使用的4种方式

         待补充

      2.ES6中箭头函数中的this

         先看几个例子

            function foo() {
              setTimeout(() => {
                console.log('id:', this.id);
              }, 100);
            }
    
            var id = 21;
    
            foo.call({ id: 42 });
            // id: 42

      上面这个例子是阮一峰ES6入门里的一个例子,他在书中提到“箭头函数体内的this对象,就是定义时所在的对象,而不是使用时所在的对象”,这种解释并不好,你也行还是不能真正理解上面这个例子。我更推荐MDN里对箭头函数this的说明“箭头功能不会创建自己的this;它使用封闭执行上下文的this值”。setTimeout里的函数的封闭上下文是foo函数,因此该箭头函数使用foo函数的this,在调用的时候,foo函数通过call将自己的id变成42,所以打印出的this.id是42。

      下面的例子是MDN的例子,会从0每隔一秒打印递增的整数0,1,2,3... 。对照这个例子再体会MDN对于箭头函数的说明。 

            function Person(){
              this.age = 0;
    
              setInterval(() => {
                console.log(this.age++)  // 传递给setInterval的函数内的this与封闭函数中的this值相同
              }, 1000);
            }
    
            var p = new Person();

      还有一点,有些同学可能因为之前看了阮一峰对箭头函数this的解释“箭头函数体内的this对象,就是定义时所在的对象”,会产生疑惑,它每次使用的是这个对象的起初的深拷贝的副本还是引用值,通俗的问就是,当执行上下文的this值上的属性变化了,箭头函数里的this上的属性是否变化呢。答案是也跟着变化,我们根据MDN的解释,它使用封闭执行上下文的this值。上面的例子其实已经可以验证这个问题了,为了更清楚一下,我们稍微改一下。

            function Person(){
              this.age = 0;
    
              setInterval(() => {
                console.log(this.age++);
              }, 1000);
            }
    
            var p = new Person();
            p.age = 50;

       我们在控制台可以看到,从50每隔1秒递增打印一个整数。

       由于 this 已经在词法层面完成了绑定,通过 call() 或 apply() 方法调用一个箭头函数时,只是传入了参数而已,对 this 并没有什么影响:

      

        var adder = {
          base : 1,
            
          add : function(a) {
            var f = v => v + this.base;
            return f(a);
          },
    
          addThruCall: function(a) {
              // console.log(this.base)
            var f = v => v + this.base;
            var b = {
              base : 2
            };
                    
            return f.call(b, a);
          }
        };
    
        console.log(adder.add(1));         // 输出 2
        console.log(adder.addThruCall(1)); // 仍然输出 2(而不是3)

      注意与一开始的例子区别,一开始的例子是对箭头函数外层函数使用call,而这个例子是直接对箭头函数使用call。addThruCall内的this与ES5一样,是调用对象的this,里面的箭头函数同样使用这个this。我们在后面加两句

        var cc = adder.addThruCall;
        console.log(cc(1))

      控制台输出NaN,想想是不是和ES5对象方法调用一样的呢。

    参考链接:1.MDN箭头函数

  • 相关阅读:
    关于博客园各项工具的使用
    Java常用的7大排序算法汇总
    Java 基本数据类型(新手必看资料)
    学习Java,还需要学好哪些知识
    JavaSE基础知识总结
    python2.7.11安装pygame包
    phpstorm打开项目目录时,出现一直在扫描文件
    laravel 通过npm搭建前端资源的注意事项
    基于laravel5.2进行rabbitmq队列服务发送接收信息
    在centos7中安装composer
  • 原文地址:https://www.cnblogs.com/zhansu/p/7878613.html
Copyright © 2011-2022 走看看