使用下划线继承

inheritance using underscore

本文关键字:继承 下划线      更新时间:2024-05-09

我得到了一个类-

Zoo.Controller = (function() {
  function Controller() {}
  Controller.prototype.params = {};
  Controller.prototype.set_params = function(params) {
    this.params = params;
    return this;
  };
  return Controller;
})();

并且我想使用_.extend 从该类继承

Zoo.Controllers.WhaleController = _.extend({
  new: function () {
    // do something
  }
}, Zoo.Controller);

当我尝试像这样实例化那个类时…

this.whale_controller = new Zoo.Controllers.WhaleController();

我得到

Uncaught TypeError: object is not a function

有可能做我想做的事吗?我读过很多关于JS中继承的文章,但我认为Undercore库已经为我解决了这个问题

正如Bergi所指出的;在JavaScript中继承并不难。您应该知道构造函数的作用以及原型的用途。这个答案可能会有所帮助,我试图通过简单易懂的例子来展示原型。您可以在浏览器JS命令行(控制台中)中复制和粘贴代码,并对其进行更改,以查看您是否了解原型在JavaScript中的行为。

要从ZooController继承,您可以:

Zoo.Controllers.WhaleController = function(args){
  Zoo.Controller.apply(this,arguments);//re use Zoo.Controller constructor
                                  //and initialize instance variables
  //instance specific members of Whale using an args object
  this.weitht=args.weight||4;
  this.wu=args.weightUnit||wu.metricTon;
  //Zoo.Controller.call(this,arg1,arg2); can be used too but I usually use
  // an args object so every function can pick out and mutate whatever they want
  // for example: var w = new WhaleController({weight:3,weightUnit:wu.metricTon});
  // now it looks more like pythons optional arguments: fn(spacing=15, object=o)
};
//set Zoo.controller.prototype to a shallow copy of WhaleController.prototype
//may have to polyfill the Object.create method if you want to support older browsers
Zoo.Controllers.WhaleController.prototype=Object.create(Zoo.Controller.prototype);
//repair constructor
Zoo.Controllers.WhaleController.prototype.constructor=Zoo.Controllers.WhaleController;
//extend Zoo.controller.prototype.set_params
Zoo.Controllers.WhaleController.prototype.set_params=function(){
  //re use parent set_params
  Zoo.Controller.prototype.set_params.apply(this,arguments);
  //and do something extra
  console.log("extra in set_params from WhaleController");
};
//WhaleController own function
Zoo.Controllers.WhaleController.prototype.whaleSpecific=function(){
  //funciton specific to WhaleController
};

在此处创建Object.create的Polyfill。

我自己也在想,这就是我想到的。

定义父项

var parentObj = function(parentMemo) {
   console.log(parentMemo);
};
parentObj.prototype = {
    parentCall : function() {
        console.log('parentCall');
    }
}

定义子项

var childObj = function(childMemo, parentMemo) {
   parentObj.call(this, parentMemo);
   console.log(childMemo);
};
_.extend(childObj.prototype, parentObj.prototype, {
    childCall : function() {
       console.log('childCall');
    }
});

构造一个新的孩子来查看结果

var newChild = new childObj("Constructing Child", "Constructing Parent");
newChild.childCall();
newChild.parentCall();

控制台结果:

Constructing Child
Constructing Parent
childCall
parentCall 

我读过很多关于JS中继承的文章,但我认为Undercore库已经为我解决了这个问题

不,Underscore没有用于原型继承的辅助函数。阅读extend的作用文档:

_.extend(destination, *sources):将源对象中的所有属性复制到目标对象,并返回目标对象。它是有序的,所以最后一个源将覆盖以前参数中相同名称的属性。

最有趣的是,它不返回函数,而是返回它的第一个参数(它是一个普通对象)。

所以,回到你读过的文章,选择一个真正具有inherit函数的框架,或者自己实现继承——这并不难。

John Resig有一篇关于实现Javascript继承的好博客文章,它可能对您有用,因为它包含了原型继承的解决方案,而Undercore extend旨在扩展简单的Javascript对象。

正如其他人所解释的,underline的extend方法创建对象实例的(非常)浅拷贝,并且不保留原型链。然而,我最近遇到了一个小型库Compose.js,其更广泛的职责是为js的OO属性提供更灵活的API。

自述文件中的第二个例子似乎几乎完全处理了您的用例——我相信在您的情况下,它会被调用如下:

Zoo.Controllers.WhaleController = Compose( Zoo.Controller, { new: function () {
  // do something
} );

您可以重用backboneJ使用的extend()函数。这是一个非常简单的函数,它也使用了_.extend()

http://backbonejs.org/docs/backbone.html#section-208

然后把它连接到你的控制器原型上,这样你就可以做一些类似的事情:

var MyController = Controller.extend({ /* your attributes, methods */  });

希望这对有帮助