简体   繁体   中英

Why is my javascript mixin not working?

Take a look at this klass implementation (from Javascript Web Applications by Alex MacCaw.) that adds prototype methods for instantiated objects:

var Class = function(){
  var klass = function(){
    this.init.apply(this, arguments);
  };

  klass.prototype.init  = function(){};

  // Shortcut to access prototype
  klass.fn = klass.prototype;

  // Shortcut to access class
  klass.fn.parent = klass;

  // Adding class properties
  klass.extend = function(obj){
    var extended = obj.extended;
    for(var i in obj){
      klass[i] = obj[i];
    }
    if (extended) extended(klass)
  };

  // Adding instance properties
  klass.include = function(obj){
    var included = obj.included;
    for(var i in obj){
      klass.fn[i] = obj[i];
    }
    if (included) included(klass)
  };

  return klass;
};

The adding instance properties bit does not work for me.

var Restaurant = new Class;

Restaurant.prototype = {
  init: function(name, cuisine, location) {
    this.name = name || 'needs a name';
    this.cuisine = cuisine || 'needs a cuisine';
    this.location = location || 'needs a location';
  }
}

Restaurant.include({
  save: function(id) {  
    return 'saved';
  },
  destroy: function(id) { /* ... */ },
  included: function(klass) {
    console.log(klass, " was included!");
  }
});

var chow = new Restaurant('Chows', 'chinese', 'mumbai');

The problem is the chow object does not respond to the save method. The included callback however works.

I get the error: Uncaught TypeError: Object #<Object> has no method 'save'

Why is that? How do I fix it?

When you execute this line:

Restaurant.prototype = {...};

You just replaced the entire prototype of the Restaurant object so it no longer has the methods that were supposed to be put there from klass . It won't have .include() for example and with no .include() , that method can't add your .save() so therefore there's no .save() .

The way this klass code works that I assume you got from the book, you don't assign to .prototype (because that wrecks stuff that is supposed to be there). You either call .include() to add new methods to the prototype or .extend() to add new methods to an instance.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM