ES6的class本质和react中须要使用bind(this)的缘由

ES6的class

咱们知道ES6新出一个规范是使用class关键字来定义一个类,这在之前是没有的
在之前,须要在javascript里实现面向对象,就须要使用prototypejavascript

什么是面向对象?

面向对象有以下几个基本特征,一般认为,只要实现了这几个特性,就认为是实现了面向对象:
1.封装
2.继承
3.多态
这里不对三个基本特征的作详细展开。只须要知道,javascript实现继承和多态都须要用到prototype
而ES6的class,本质上仍是ES5的prototype的语法糖java

什么是语法糖?

语法糖就是提供了一种全新的方式书写代码,可是其实现原理与以前的写法相同。
语法糖能够说是普遍存在于各类计算机代码中,包括C语言中的a[i]其实就是*a+i的语法糖。而今天对于咱们来讲,a[i]其实已经很广泛和经常使用了,因此也没有人提这是语法糖这回事了。由于终极来讲,全部语言都是汇编语言的语法糖:)react

class foo{
    constructor(){
    }
    a(){}
    b(){}
}

// 等价于
function foo(){};
foo.prototype = {
    constructor(){},
    a(){},
    b(){},
}

ES6的class跟ES5的定义方式用几个不一样

1.没有变量提高
2.this指向不一样函数

先来看1:this

test(); // 输出'test'
function test(){
    console.log('test');
}

咱们知道即使在定义test函数以前执行test(),也是会获得结果的。这是由于解析javascript代码的时候会把全部的function test(){}这类代码(即正常定义函数)都提高到最上方去定义。spa

可是这么执行不行:prototype

let a = new test(); // 报错
class test(){}

再看2:code

class Animal {
    printName () {
      this.print('Hello animal');
    }
    print(name) {
      console.log(name);
    }
}
const animal = new Animal();
animal.printName(); // 输出'Hello animal'
const { printName } = animal;
printName(); // 报错: Cannot read property 'print' of undefined

若是执行了bind对象

class Animal {
    constructor(){
        this.printName = this.printName.bind(this);
    }
    printName () {
      this.print('Hello animal');
    }
    print(name) {
      console.log(name);
    }
}
const animal = new Animal();
animal.printName(); // 输出'Hello animal'
const { printName } = animal;
printName(); // 输出'Hello animal'

发生了什么?

animal中的printName函数的this本来指向的是执行环境,若是不执行bind,那么printName函数的this指向window。
在执行new Animal()的时候,若是执行了bind,那么从animal中获取的printName函数,其this对象已经被绑定到了constructor的this,即animal上。
如下是this的指向
clipboard.pngblog

那么咱们为何须要在react里bind(this)呢?

简单来讲,就是react在调用render方法的时候,会先把render里的方法赋值给一个变量(好比变量foo),而后再执行foo()。
具体来讲,以典型的绑定点击事件为例

<div onClick={this.clickHandler}></div>

react构建虚拟DOM的时候,会把this.clickHandler先赋值给一个变量。咱们假设是变量clickFunc = this.clickHandler;
而后,把虚拟DOM渲染成真实DOM的时候,会把onClick属性值替换成onclick,并给onclick赋值clickFunc

在复杂的状况中,可能存在屡次传递,若是不进行bind,那么this的指向是必定会丢失的。

为何react不本身集成bind到生命周期里?

1是,没有特别合适集成bind的地方2是,并非全部的函数都须要bind3是,随意集成bind可能致使效率低下

相关文章
相关标签/搜索