ES6的class本质和react中需要使用bind(this)的原因

栏目: JavaScript · 发布时间: 5年前

内容简介:我们知道ES6新出一个规范是使用class关键字来定义一个类,这在以前是没有的在以前,需要在javascript里实现面向对象,就需要使用prototype面向对象有如下几个基本特征,通常认为,只要实现了这几个特性,就认为是实现了面向对象:

ES6的class

我们知道ES6新出一个规范是使用class关键字来定义一个类,这在以前是没有的

在以前,需要在javascript里实现面向对象,就需要使用prototype

什么是面向对象?

面向对象有如下几个基本特征,通常认为,只要实现了这几个特性,就认为是实现了面向对象:

1.封装

2.继承

3.多态

这里不对三个基本特征的做详细展开。只需要知道,javascript实现继承和多态都需要用到prototype

而ES6的class,本质上还是ES5的prototype的语法糖

什么是语法糖?

语法糖就是提供了一种全新的方式书写代码,但是其实现原理与之前的写法相同。

语法糖可以说是广泛存在于各种计算机代码中,包括 C语言 中的a[i]其实就是*a+i的语法糖。而今天对于我们来说,a[i]其实已经很普遍和常用了,所以也没有人提这是语法糖这回事了。因为终极来说,所有语言都是汇编语言的语法糖:)

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

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

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

1.没有变量提升

2.this指向不同

先来看1:

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

我们知道即便在定义test函数之前执行test(),也是会得到结果的。这是因为解析javascript代码的时候会把所有的function test(){}这类代码(即正常定义函数)都提升到最上方去定义。

但是这么执行不行:

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

再看2:

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的指向

ES6的class本质和react中需要使用bind(this)的原因

那么我们为什么需要在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是,并不是所有的函数都需要bind

3是,随意集成bind可能导致效率低下


以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

R语言实战

R语言实战

卡巴科弗 (Robert I.Kabacoff) / 高涛、肖楠、陈钢 / 人民邮电出版社 / 2013-1 / 79.00元

数据时代已经到来,但数据分析、数据挖掘人才却十分短缺。由于“大数据”对每个领域的决定性影响, 相对于经验和直觉,在商业、经济及其他领域中基于数据和分析去发现问题并作出科学、客观的决策越来越重要。开源软件R是世界上最流行的数据分析、统计计算及制图语言,几乎能够完成任何数据处理任务,可安装并运行于所有主流平台,为我们提供了成千上万的专业模块和实用工具,是从大数据中获取有用信息的绝佳工具。  本书从解决......一起来看看 《R语言实战》 这本书的介绍吧!

SHA 加密
SHA 加密

SHA 加密工具

XML、JSON 在线转换
XML、JSON 在线转换

在线XML、JSON转换工具

UNIX 时间戳转换
UNIX 时间戳转换

UNIX 时间戳转换