• 首页 首页 icon
  • 工具库 工具库 icon
    • IP查询 IP查询 icon
  • 内容库 内容库 icon
    • 快讯库 快讯库 icon
    • 精品库 精品库 icon
    • 问答库 问答库 icon
  • 更多 更多 icon
    • 服务条款 服务条款 icon

React的constructor super作用是什么意思为什么要进行bind绑定

武飞扬头像
小丽丽lilly
帮助1

最近有些迷惑一个事情,就是在写react组件的时候,有时候写constructor,有时候不写,呃呃呃呃呃,虽然不起眼,但是这到底是一个什么机制呢,好好研究了一下,发现涉及到的东西还不少,这并不是出现在react的东西,而是涉及到类和继承的问题的,决定写下来总结一下。虽然对于使用并不影响,但是只知其然不知其所以然,慢慢就会变得迷茫。。。。
参考文章
Why Do We Write super(props)?
阮一峰:Class 的继承
为什么在React Component需要bind绑定事件
MDN类体和方法定义

1.constructor方法到底是啥?
MDN对类和构造函数的解释中说明

constructor方法是一个特殊的方法,这种方法用于创建和初始化一个由class创建的对象。
一个构造函数可以使用 super 关键字来调用一个父类的构造函数

2.写不写?

class Clock extends React.Component {
  constructor(props) {
    super(props);
    this.state = {date: new Date()};
  }
  render() {
    return (
      <div>
        <h1>Hello, world!</h1>
        <h2>It is {this.state.date.toLocaleTimeString()}.</h2>
      </div>
    );
  }
}

以上是react官网粘贴下来的代码,但是在实际写的时候,不写constructor,super也是没有问题的,并不会影响的执行。不写 constructor(props) {super(props);的部分,并不是我们在运行中不再运行了,如果子类没有定义constructor()方法,这个方法会默认添加,并且里面会调用super()。也就是说,不管有没有显式定义,任何一个子类都有constructor()方法。

class ColorPoint extends Point {
}
// 等同于
class ColorPoint extends Point {
  constructor(...args) {
    super(...args);
  }
}

3.如果写了constructor,就必须写super
如果只写了constructor,而不写super,使用this就会出现报错学新通
为什么子类的构造函数,一定要调用super()?原因就在于 ES6 的继承机制,与 ES5 完全不同。

ES5 的继承机制,是先创造一个独立的子类的实例对象,然后再将父类的方法添加到这个对象上面,即“实例在前,继承在后”。
ES6 的继承机制,则是先将父类的属性和方法,加到一个空的对象上面,然后再将该对象作为子类的实例,即“继承在前,实例在后”。这就是为什么 ES6 的继承必须先调用super()方法,因为这一步会生成一个继承父类的this对象,没有这一步就无法继承父类。

这意味着新建子类实例时,父类的构造函数必定会先运行一次。

另一个需要注意的地方是,在子类的构造函数中,只有调用super()之后,才可以使用this关键字,否则会报错。这是因为子类实例的构建,必须先完成父类的继承,只有super()方法才能让子类实例继承父类。

super虽然代表了父类A的构造函数,但是返回的是子类B的实例,即super内部的this指的是B的实例,因此super()在这里相当于A.prototype.constructor.call(this)。
4.加不加props?
只有一个理由需要传递props作为super()的参数,那就是你需要在构造函数内使用this.props
解释引自 What’s the difference between “super()” and “super(props)” in React when using es6 classes?

There is only one reason when one needs to pass props to super():
When you want to access this.props in constructor.
(Which is probably redundant since you already have a reference to it.)

 constructor(props){
        super(props)
        this.state = {
            name :this.props.name。//在constructor中访问 不加props会报错
        }
    }
    componentDidMount(){
        console.log(this.props.name) //不在constructor中 不加props不会报错
    }

写到这里,想起来一个事情,就是react中的函数推荐使用bind进行事件绑定,但是在使用箭头函数以后就不再需要再绑定了,大家都知道是因为this的指向发生了变化导致this报错,但是为什么会发生指向变化,this又指向了哪里呢?
5.react中的事件指向问题。
其实这个问题也是js的问题,令人用起来比较麻烦的this问题。最直接的一点就是谁调用this就会指向谁,具体问题再具体分析啦!

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

React 通过 React.createElement 方法模拟 document.createElement 来创建 DOM(当然React创建的是虚拟DOM)。 属性中 onClick 指向 this.handleClick 方法,看起来都没有问题。
但是render方法中被Babel编译后的样子:

 render() {
    return React.createElement(
      'button',
      { onClick: this.handleClick },
      'Hello'
    );
  }

此时的onClick即是中间变量,相当于把函数传递给了onClick这个变量,等点击的时候会调用方法,所以在调用的时候其实是谁调用onclick的问题,在React class组件中,在执行click事件时类似于 element.addEventListener(‘click’, callback, false),该callback失去了隐式绑定的上下文,指向了全局对象,严格模式下的this值为 undefined。
参考MDN中类的说明

当调用静态或原型方法时没有指定 this 的值,那么方法内的 this 值将被置为 undefined。即使你未设置 “use
strict” ,因为 class 体内部的代码总是在严格模式下执行。

所以要绑定this。使用bind或者使用箭头函数,使this绑定在当前的上下文。

这篇好文章是转载于:学新通技术网

  • 版权申明: 本站部分内容来自互联网,仅供学习及演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,请提供相关证据及您的身份证明,我们将在收到邮件后48小时内删除。
  • 本站站名: 学新通技术网
  • 本文地址: /boutique/detail/tanhfkhkaf
系列文章
更多 icon
同类精品
更多 icon
继续加载