Domanda

I'm trying to level-up in JavaScript (I'm not using it much at work), and have pretty well wrapped my head around Constructor functions and how to instantiate new Objects that inherit properties from them.

But usually to really learn something, I need to use it in a real project I'm working on and see it in action.

Problem is, everything I'm reading uses examples like these to explain inheritance:

function Apple (type) {
    this.type = type;
    this.color = "red";
    this.getInfo = getAppleInfo;
}

or

function Car( model, year, miles ) {

  this.model = model;
  this.year = year;
  this.miles = miles;

  this.toString = function () {
    return this.model + " has done " + this.miles + " miles";
  };
}

or

function makeBaby(parent, name) {

  var baby = Object.create(parent);

  baby.name = name;

  return baby;
}

As you might imagine, these sorts of examples (Fruit, Cars, and Parents) are definitely helpful for the purposes of learning concepts, but not really in putting them into practice.

Does anyone have an example of how prototypal inheritance might work in a production-level web application?

È stato utile?

Soluzione

It's not just prototypal inheritance, but the use-cases also apply to classical inheritance.

Generally, you want to extend the properties and functionalities of one class to another. A beautiful example of this is a view class. It has a draw method that draws to a screen. A great way to reuse code.

So Instead of you duplicating by hand all of the properties of one class to another, you would simply extend from the base class, and you would have all the functionalities of it, as well as adding your own implementations.

An example code that does not use inheritance:

/**
 * View1
 */
function View1 {
  this.viewId = 'view-1';
  this.template = '<some html here>'
}

View1.prototype.draw = function () {
  var ourView = document.getElementById(this.viewId);

  // ps. I know this is redundant, but it's here for illustration purposes.
  var newElement = document.createElement('div');
  ourView.appendChild(newElement);

  ourView.innerHTML = this.template;
}


/**
 * View2
 */
function View2 {
  this.viewId = 'view-2';
  this.template = '<some html here>'
}

View2.prototype.draw = function () {
  var ourView = document.getElementById(this.id);

  // ps. I know this is redundant, but it's here for illustration purposes.
  var newElement = document.createElement('div');
  ourView.appendChild(newElement);

  ourView.innerHTML = this.template;
}

As you can see above, there are a lot of duplicate code.

Compare that with code that uses inheritance:

/**
 * View1
 */
function View1 {
  this.viewId = 'view-1';
  this.template = '<some html here>'
}

View1.prototype.draw = function () {
  var ourView = document.getElementById(this.viewId);

  // ps. I know this is redundant, but it's here for illustration purposes.
  var newElement = document.createElement('div');
  ourView.appendChild(newElement);

  ourView.innerHTML = this.template;
};

/**
 * View2
 */
function View2 {
  this.viewId = 'view-2';
  this.template = '<some html here>'
}

Object.assign(View2.prototype, View1.prototype);

View2 never needs to re-implement code from View1. Instead, it simply reuses it.

Altri suggerimenti

Prototypal inheritance is useful anywhere you want to use Object Oriented approach with inheritance to model your problems.

One good example is how Backbone.js provides base classes such as Model, Collection and View. In your application you extend those base classes to do something specific, for example

var ProfileSummary = Backbone.View.extend({
  render: function () {
    this.$el.html("Profile summary view");
  }
});

Now ProfileSummary is a class that has (inherits) all of the Backbone.View methods and functionality, but you tweak what the render function does.

Note that the extend method is Backbone's way of providing you with any easy way to extend these classes using the prototypal inheritance - see the code for more details https://github.com/jashkenas/backbone/blob/e6f8f7ea69370b0891cc969a2c68ebb78ad6e49b/backbone.js#L1551-L1588

You can create several layers in your class hierarchy if that helps your application. For example.

var MyBaseView = Backbone.View.extend({
  //common functionality in all views within yur app
});

var ProfileSummary = MyBaseView.extend({
   //functionality specific to the profile summary view
});

var ProfileSummaryEditor = ProfileSummary.extend({
  //makes the profile summary editable
});

Hope this helps. Let me know if I misinterpreted your question.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top