如何创建函数模型?

时间:2013-12-11 23:38:27

标签: javascript class model inheritance

我想创建一个类的模型,比如说

var car = function(){
  var color;
  this.setColor = function(clr){
    color = clr;
  }
}

现在我想要更多的课程,例如volvo()。但是我也想要car()所有的东西在volvo()中使用它,就像这样

var volvo = function(){
  ...probably some code here
  this.getColor = function(){
    return color;
  }
}

我该怎么做?

4 个答案:

答案 0 :(得分:2)

您要实现的目标称为继承,因为JavaScript不是基于类的,如Java,C#和其他语言,并且它基于原型,所以它并不容易实现。

有很多方法可以实现它:

一种方法是使用Backbone.jsAngularJSEmber.js等框架。然后在您的模型类中,基本上您可以使用Extend关键字,然后开箱即可获得继承。

另一种方法是将John Resig(jQuery的创建者)编写的以下代码包含在您的应用程序中:

    /* Simple JavaScript Inheritance
     * By John Resig http://ejohn.org/
     * MIT Licensed.
     */
     // Inspired by base2 and Prototype
    (function(){
  var initializing = false, fnTest = /xyz/.test(function(){xyz;}) ? /\b_super\b/ : /.*/;

  // The base Class implementation (does nothing)
  this.Class = function(){};

  // Create a new Class that inherits from this class
  Class.extend = function(prop) {
    var _super = this.prototype;

    // Instantiate a base class (but only create the instance,
    // don't run the init constructor)
    initializing = true;
    var prototype = new this();
    initializing = false;

    // Copy the properties over onto the new prototype
    for (var name in prop) {
      // Check if we're overwriting an existing function
      prototype[name] = typeof prop[name] == "function" &&
        typeof _super[name] == "function" && fnTest.test(prop[name]) ?
        (function(name, fn){
          return function() {
            var tmp = this._super;

            // Add a new ._super() method that is the same method
            // but on the super-class
            this._super = _super[name];

            // The method only need to be bound temporarily, so we
            // remove it when we're done executing
            var ret = fn.apply(this, arguments);
            this._super = tmp;

            return ret;
          };
        })(name, prop[name]) :
        prop[name];
    }

    // The dummy class constructor
    function Class() {
      // All construction is actually done in the init method
      if ( !initializing && this.init )
        this.init.apply(this, arguments);
    }

    // Populate our constructed prototype object
    Class.prototype = prototype;

    // Enforce the constructor to be what we expect
    Class.prototype.constructor = Class;

    // And make this class extendable
    Class.extend = arguments.callee;

    return Class;
  };
})();

加载此代码后,您将能够将其用于解决您的问题:

var Car = Class.Extend({
  setColor: function(clr){
    color = clr;
  }
});

var volvo = Car.Extend({
   getColor: function () {
      return color;
   }
});

JavaScript Inheritance by John Resig帖子中了解相关信息。祝你好运!

答案 1 :(得分:1)

你可以在没有任何额外库的情况下完成它 - 它只是稍微冗长。

jsFiddle

首先设置一个car类并为其提供一些方法(setColorsetMakesetModel):

function car(make,model){
    console.log( 'car constructor' );
    this.setMake( make );
    this.setModel( model );
}
car.prototype.setColor = function(color){ this.color = color; };
car.prototype.setMake  = function(make ){ this.make  = make;  };
car.prototype.setModel = function(model){ this.model = model; };
car.prototype.toString = function(){ return 'This is a ' + this.color + ' ' + this.make + ' ' + this.model + ' car' };

然后你可以继承汽车:

function volvo( model ){
    console.log( 'volvo constructor' );
    car.call( this, 'volvo', model );
}
volvo.prototype = Object.create( car.prototype );
volvo.prototype.constructor = volvo;

然后看看各个部分:

  • function volvo( model ){}定义了volvo类。
    • 在构造函数car.call( this, 'volvo', model );中,用于使用固定的make volvo调用父类的构造函数。
  • volvo.prototype = Object.create( car.prototype );volvo类设置为从car类继承。
  • volvo.prototype.constructor = volvo;用于确保volvo类使用volvo构造函数(没有此行,前一个语句会导致它使用car构造函数)。< / LI>

然后我们可以测试一下:

var c = new car('Ford', 'Fiesta');
c.setColor('Red');
console.log( c.toString() );

var v = new volvo( 'S10' );
v.setColor( 'Grey' );
console.log( v.toString() );

输出是(包括显示调用构造函数的日志条目):

car constructor
This is a Red Ford Fiesta car
volvo constructor
car constructor
This is a Grey volvo S10 car

如果你需要Object.create的填充物,那么你可以使用:

if (!Object.create) {
  Object.create = (function(){
    function F(){}

    return function(o){
      if (arguments.length != 1) {
          throw new Error('Object.create implementation only accepts one parameter.');
      }
      F.prototype = o
        return new F()
    }
  })()
}

答案 2 :(得分:0)

function Car(color) {
    this.getColor = function() {
        return color;   
    };

    this.extend = function() {
        function F() {};
        F.prototype = this;
        return new F();
    };
}

car = new Car("black");
console.log(car.getColor());

vw = car.extend();
vw.slogan = function() { return "Das Auto"; };

console.log(vw.getColor());
console.log(vw.slogan());

gulf = vw.extend();
gulf.isHatchBack = function() { return true; };

console.log(gulf.getColor());
console.log(gulf.slogan());
console.log(gulf.isHatchBack());

答案 3 :(得分:0)

可能你会发现这也很有趣:http://jsbin.com/IgOCAvI/1/edit

function Car() {
  this.carData = {};
}

Car.prototype = {

  set: function(ob) {
    var obType = Object.prototype.toString.call(ob);
    if( ob && obType.match('Obj') ){
      for (var key in ob) {
        if ( ob.hasOwnProperty(key) ){
          this.carData[key] = ob[key];
          // console.log("Stored: "+ key +':'+ ob[key] ); // TEST
        }
      }
    }else{
      // alert(ob +' ('+obType+')\n is not an Object!');
    } 
  }, 

  get: function(key) {
    if(typeof key == "string"){
      var arr = key.replace(/ /g, "").split(',');
      for(var i=0; i<arr.length; i++){ arr[i] = this.carData[arr[i]]; }
      // console.log( arr ); // TEST
      return arr;
    }else{ // Return the whole Object!
      // console.log( JSON.stringify(this.carData, null, 2) ); // TEST
      return this.carData;
    }
  }

};

用法:

// Create new instance of Car 
var car1 = new Car();

// Populate with values
car1.set({manufacturer:"Volvo", model:"S40", color:"green", doors:5, damage:"front fender"});
// Get Array collection
console.log(  car1.get("color")  );                    // [Green]
console.log(  car1.get("color, doors, firstOwner")  ); // [Green, 5, undefined]
// Get whole Object
console.log(  car1.get()  );                           // [object Object]
// Get specific value from Object
console.log(  car1.get().color  );                     // "Green"
// Let's change a key value
car1.set({color:"red"});
// Test 
console.log(  car1.get()  );  


//  CAR2
var car2 = new Car();
// let's see if the car2 inherited some property of car1
console.log( car2.get('color') );  // [undefined] // nope.
car2.set({manufacturer:"Nissan", model:"Micra", color:"gray", doors:3, damage:"none"});
// ...