JavaScript中的原型继承如何真正起作用? [英] How does prototypal inheritance in JavaScript really works?

查看:149
本文介绍了JavaScript中的原型继承如何真正起作用?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I’m still not fully understanding the inheritance dychotomy (prototypal vs. classical) in JavaScript.

如果只是原型的语法糖,我应该如何去糖?

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

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

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

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

So, is there a way to get stateful component using native 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'));

由于内部lib的限制,似乎这样的事情无效。 但是为什么我们不能在更自然的原型JavaScript中使用它?

Seems something like this won’t work because of inner lib’s restrictions. But why we can’t use it in more natural to prototypal nature of JavaScript?

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

There’s a note from the official docs: 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 主要是关于继承?

But isn’t class mostly about inheritance?

我很困惑,想听听你对我在做什么的看法我错了吗?

I’m very confused and would like to hear your opinions of what I am doing and thinking wrong?

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

I’ve asked that question at Reactiflux and Brendan Hurley proposed this: 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'));

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

Is his solution truly prototypal?

以下是一些参考资料:

  • http://javascript.crockford.com/prototypal.html
  • https://medium.com/javascript-scene/the-two-pillars-of-javascript-ee6f3281e7f3
  • http://henleyedition.com/making-inheritance-make-sense-with-object-create/

*问题主要是关于继承,而不是关于React。这里的反应只是一个参考。

推荐答案

所以,就像其他人所说的那样,思考课程的最佳方式在Javascript中作为原型继承的语法糖。最好避免将经典继承与其他语言中的类联系起来,特别是如果你已经在大学/学校教过它。

So, like others have said, the best way to think about classes in Javascript is as syntactical sugar over prototypal inheritance. It's best to avoid the association of classical inheritance and classes in other languages, particularly if you have been taught it in university/school.

原型继承可以被认为是< a href =http://www.crockford.com/javascript/inheritance.html =nofollow noreferrertitle =more detail>比传统继承更具表现力。

Prototypal inheritance can be considered to be more expressive than classical inheritance.

在JS中使用'class'关键字在语法上更接近经典继承。

Using the 'class' keyword in JS is syntactically closer to classical inheritance.

例如,在UI中有这些组件:Link ,MediaLink,ImageLink&视频链接。在经典继承中,您可能想要一个Link类,一个扩展Link的MediaLink类,以及一个VideoLink& amp;扩展MediaLink类的ImageLink类,其中MediaLink是一个抽象类(不进行实例化)。如果你使用原型继承实现具有有状态React组件的这个层次结构,理论上可以通过调用super(或调用 React.Component.apply(this,props); 如上面的答案),然而React的核心,即'渲染'将是一个小抽象,难以扩展。链接可能会返回< a ...>链接< / a> ,MediaLink会返回什么? VideoLink如何与其父级的回归一起工作?或者你是否开始否定父渲染函数并完全替换它们?它在这一点上变得尴尬,它看起来有点像意大利面。

For example, you have in your UI these components: Link, MediaLink, ImageLink & VideoLink. In classical inheritance, you might be tempted to have a Link class, a MediaLink class that extends Link, and VideoLink & ImageLink classes that extend MediaLink class where MediaLink is an abstract class (not to be instantiated). If you were to implement this hierarchy with stateful React components using prototypal inheritance, the states could theoretically be easily manipulated by calling super (or calling React.Component.apply(this, props); as in an answer above), however the core of React, i.e. 'render' would be a little abstract and difficult to extend. A link might return <a ...>link</a>, what would a MediaLink return? How would a VideoLink work with the return of its parent? Or do you begin to negate the parent rendering functions and replace them entirely? It gets awkward at this point and it begins to look a little like spaghetti.

相反,你可以组成组件。在经典继承中,您可以将Component类视为继承自抽象类,React.Component的 final class 。要实现上述功能,您可以向类中添加可能对很多类很常见的行为。例如,组件TextLink,VideoLink& ImageLink都有一个布尔状态'clicked'。我认为这篇文章很好地总结了这些想法。

Instead, you can compose components. In classical inheritance, you can think of your Component class as a final class that has inherited from an abstract class, React.Component. To implement the above, you add behaviour to your class that may be common to a lot of classes. For example, Components TextLink, VideoLink & ImageLink all have a boolean state 'clicked'. I think this article summarises these ideas pretty well.

组合组件的另一种方法是将组件与其他组件包装在一起,并通过props将状态传递给子组件。一个非常粗糙的例子可能是:Link,SwitchedLink。 Link类具有prop'active',用于确定它是否处于活动状态。 Switched链接将呈现< Link /> < Link active /> 作为单个孩子取决于自己的状态。孩子是无国籍的。父母有州。这些是React的常见模式,因此不需要经典的多级继承结构。

Another way of composing components is by wrapping components with other components and passing state via props to their children. A really crude example might be: Link, SwitchedLink. The Link class has a prop 'active' which determines whether or not it is active. The Switched link will render either <Link /> or <Link active /> as a single child depending on its own state. The child is stateless. The parent has state. These are common patterns with React and thus why there is no need for a classical multiple level inheritance structure.

我希望能解决你的问题。

I hope that addresses your question.

这篇关于JavaScript中的原型继承如何真正起作用?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆