javascript - JavaScript 中的原型(prototype)继承是如何工作的?

标签 javascript reactjs inheritance

我仍然没有完全理解 JavaScript 中的继承二分法(原型(prototype)与经典)。

如果 class 只是原型(prototype)的语法糖,我应该如何去除它的糖分?

你能告诉我用类和原型(prototype)创建 React 元素的不同方法吗(即没有 classReact.createClass)?

那么,有没有办法使用原生 Object.create 获取有状态组件?

像这样:

const Hello = Object.create(React.Component.prototype, {
  componentDidMount: {
    value: function() {
      alert('Mounted');
    }
  },
  render: {
    value: function() {
      return <div>I love StackOverflow community! It is so helpful and friendly</div>;
    }
  }
});

ReactDOM.render(<Hello />, document.getElementById('root'));

由于内部库的限制,这样的事情似乎行不通。 但为什么我们不能在 JavaScript 的原型(prototype)性质中更自然地使用它呢?

官方文档中有一条注释:https://facebook.github.io/react/docs/composition-vs-inheritance.html#so-what-about-inheritance

[...] we haven't found any use cases where we would recommend creating component inheritance hierarchies

但是 class 主要不是关于继承吗?

我很困惑,想听听您对我做的和想的错的看法?

我在 Reactiflux 上问过这个问题,Brendan Hurley 提出了这个问题:https://codepen.io/niechea/pen/xdVEvv?editors=0010

function MyComponent(props) {
  this.props = props;
  this.state = {
    clickCount: 0,
  };
}

MyComponent.prototype = Object.create(React.Component.prototype);

MyComponent.prototype.clickHandler = function() {
  this.setState({
    clickCount: this.state.clickCount + 1,
  });
}

MyComponent.prototype.render = function() {
  return (
    <div>
      <p>Hello, {this.props.name}.</p>
      <p>You have clicked {this.state.clickCount} time(s)!</p>
      <button onClick={this.clickHandler.bind(this)}>Click me</button>
    </div>
  );
}

ReactDOM.render(<MyComponent name="Bogdan" />, document.getElementById('app'));

他的解决方案真的是原型(prototype)吗?


这里有一些引用:


* 问题主要是关于继承,而不是关于 React。这里的 React 只是一个引用。

最佳答案

If the class is just a syntactic sugar over prototypes, how I'm supposed to de-sugar it?

例如这是一个good article就此事。因此,如果您使用 class 创建了实体 Animal:

class AnimalES6 {
    constructor(name) {
        this.name = name;
    }

    doSomething() {
        console.log("I'm a " + this.name);
    }
}

var lionES6 = new AnimalES6("Lion");
lionES6.doSomething();

原型(prototype)版本看起来像这样:

var Animal = (function () {
    function Animal(name) {
        this.name = name;
    }
    // Methods
    Animal.prototype.doSomething = function () {
        console.log("I'm a " + this.name);
    };
    return Animal;
})();

var lion = new Animal("Lion");
lion.doSomething();

extend 功能更复杂(例如继承的 TypeScript 模拟):

var __extends = this.__extends || function (d, b) {
    for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p];
    function __() { this.constructor = d; }
    __.prototype = b.prototype;
    d.prototype = new __();
};

May you show me the different approaches in creating React elements with classes and prototypes (i.e. without class & React.createClass)?

这个问题也已经回答了 SO 问题,例如this one .

但是,在我看来,真正的问题是:你想要吗?

自从您链接了 Eric Elliot 的文章后,您可能注意到在 JavaScript 世界中围绕 EC6 的 classes 存在一种争议。除了您发布的示例之外,还有一些来自更多开发人员的意见汇总,例如this github repo , here和更多。也有文章捍卫class的目的...

无论如何,React 的创建者似乎已经接受了 classes 的“邪恶”,正如您所指出的,在尝试对 React 使用原型(prototype)方法时会遇到问题。所以在我看来:为什么要费心呢?我也更喜欢 javascript 的原型(prototype)性质,我也喜欢 ReactJS 框架,但在我看来,最好提出一些结合两者优点的新框架,比如“Protypal React”,而不是试图强制原型(prototype)制作在 React 不打算用于此类用途时。

But isn’t class mostly about inheritance?

这可能在评论中得到了回答,但没有。类有其优势,因为Composition 设计概念优于继承。它depends on the needs但是许多框架/库建立在面向对象的语言之上,这些语言使用类来拥抱组合而不是继承,例如团结。

无论如何,这是一个非常好的问题,我也想分享我对此事的看法。希望它能帮助您形成意见。

关于javascript - JavaScript 中的原型(prototype)继承是如何工作的?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43529107/

相关文章:

javascript - React JS 的输入范围

javascript - React-sound 不播放项目文件夹中的 mp3 文件

C# - 泛型和继承问题

javascript - 谷歌浏览器背景页建议/帮助

javascript - 闭包中的 var functionName 与 functionName 赋值

c# - 如何在 asp.net 中获得确认弹出窗口

reactjs - MUI v5 + 样式化() + ListItemButton : property 'to' /'component' does not exist

javascript - React Native TextInput onSubmitEnding 不起作用 - 创建合成事件

java - 您可以从一个单独的类调用父类(super class)中的方法,该类将所述父类(super class)的子类作为对象吗?

c++ - 为什么我的程序输出一个巨大的小数?