Prototype chain in Javascript not updated

[亡魂溺海] 提交于 2019-12-11 03:59:52

问题


I'm trying to understand prototypal inheritance in Javascript, but failing to apply to the following case. Any help would be appreciated.

I'm defining a constructor as follows:

var base = function() {
    var priv = "private"; // Private
    var publ = "public";  // Public through a getter/setter (below)

    // The object to return
    var f = {};

    f.publ = function (new_val) {
        if (!arguments.length) {
          return publ;
        }
        publ = new_val;
        return f;
    };

    return f;
};

With this constructor, I can create objects by calling base();. These objects have a public method (publ).

Now, following the same structure, I would like to have a new constructor that creates objects that inherits from objects created by the "base constructor" defined above:

var myclass = function () {

  // Other parameters defined here

  var f = function () {
      // publ is inherited
      console.log(f.publ());
  };

  // Trying to set the prototype of f to the object created by "base()"
  f.prototype = base();

  // Other methods defined here

  return f;
};

With f.prototype = base(); I want to make f inherit all the methods that are defined in the object returned by base(), but trying to call f.publ complains because f doesn't have method publ

Any help in understanding what is going on would be welcome

M;


回答1:


The most common way to do prototypal inheritance is as follows:

function Base() {
    var priv = "private";
    this.publ = "public";
}

You can now create instances of Base using new Base. Next we create MyClass:

MyClass.prototype = new Base;

function MyClass() {
    alert(this.publ);
}

Finally you can create instance of MyClass using new MyClass as follows:

var a = new MyClass; // alerts "public"

See the demo for yourself: http://jsfiddle.net/b3QyE/


Prototypal inheritance in JavaScript can get a little confusing because it's constructor-centric instead of prototype-centric which is why I prefer using the following utility function to create "classes":

function defclass(base, body) {
    var uber = base.prototype;
    var prototype = Object.create(uber);
    var constructor = (body.call(prototype, uber), prototype.constructor);
    constructor.prototype = prototype;
    return constructor;
}

Using defclass you can now restructure your code as follows:

var Base = defclass(Object, function () {
    this.constructor = function () {
        var priv = "private";
        this.publ = "public";
    };
});

var MyClass = defclass(Base, function (uber) {
    this.constructor = function () {
        uber.constructor.call(this);
        alert(this.publ);
    };
});

It's much more readable and understandable. Everything is encapsulated within a single function scope and nothing is dangling out of place. In addition you don't need to understand prototypal inheritance to use it. See the updated demo: http://jsfiddle.net/b3QyE/2/

If you notice we're calling the Base class constructor function from the MyClass constructor. This allows you to initialize the instance using the Base class constructor. You can call any method of the Base class via uber.


To learn more about prototypal inheritance take a look at the following answers:

  1. JavaScript inheritance and the constructor property
  2. How to achieve pseudo-classical inheritance right on the class declaration?
  3. Benefits of prototypal inheritance over classical?


来源:https://stackoverflow.com/questions/21653887/prototype-chain-in-javascript-not-updated

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!