【问题标题】:Creating clean, inheritable objects in JavaScript在 JavaScript 中创建干净、可继承的对象
【发布时间】:2014-12-23 16:44:28
【问题描述】:

我正在处理一个相当大的 JavaScript 项目,并尝试对其进行重构,以使其表现出更多的 JavaScript 方式。我真正想要引入的一件事是使继承可用,因为这非常适合我正在做的大部分工作,但是以易于阅读和遵循的方式使用原型和继承似乎有点困难不会陷入 JavaScript jam。

我有这样的事情:

MyMammal = function( name ) {
    if ( 0 < arguments.length )
    {
       this.init(name);
    }
}
MyMammal.prototype=  {
    init: function( name ) {
        this.name= name;
    },

    getName: function() {
        return this.name;
    }
}

那么对于派生自MyMammal的类,我是这样工作的:

MyDog = function( name, breed ) {
    if ( 0 < arguments.length ) 
    {
        this.init( name, breed );
    }
}
MyDog.prototype = Object.create( MyMammal.prototype );

_.extend( MyDog.prototype, {
    init: function( name, breed )
    {
        this.name = name;
        this.breed = breed;
    },

    getBreed: function() 
    {
        return this.breed;
    }
});

现在,只要我从方法调用中获得预期的结果,这就是有效的,但如果我尝试使用 isPrototypeOf,JavaScript 似乎不知道 MyMammalMyDog 的原型,尽管它确实识别MyDog 的实例是 instanceof MyMammal

据我了解,除了能够轻松创建子类的传统优势之外,JavaScript 原型还共享函数,因此使用它们应该更节省内存。我的问题首先是这个模型是否能够利用这一点(我不明白为什么它不能,但这就是我要问的原因),其次是使用这种类型的结构是否有任何主要缺点大型 JS 应用程序的代码?我正在尝试以一种惯用的 JavaScript 方式工作,而且我不太担心将我的局部变量保密。

【问题讨论】:

  • 不错的代码,_.extend 是从哪里来的。 IE11 不支持这个
  • @Mouser _ 是下划线或lodash库
  • @Mouser 是 Underscore (underscorejs.org/#extend) 的一部分,这是自从我开始使用它以来我就离不开它的库之一......
  • @glenatron 好的!。我开始摆弄你的代码。 MyMammal.prototype.isPrototypeOf([instance]) 返回 true。
  • @MyMouser,啊,知道这很有用。我可能错过了那里的“原型”步骤。

标签: javascript oop inheritance underscore.js prototype


【解决方案1】:

例如:

MyMammal = function( name ) {
    if ( 0 < arguments.length )
    {
       this.init(name);
    }
}
MyMammal.prototype=  {
    init: function( name ) {
        this.name= name;
    },

    getName: retrieveNameOfMammal}; //here is where the fun happens

function retrieveNameOfMammal()
{
    return this.name;
}

MyDog = function( name, breed ) {
     MyMammal.apply(this, name); //this will apply all properties and functions from MyMammal, so you do not have to recreate this.init every time.
 }

【讨论】:

  • 这不是将它们添加到原型中发生的情况吗?我的理解是原型函数是跨实例共享的,但函数成员函数不是。因此,如果我在 MyMammal 中有一个函数,那将是每个实例,但在 MyMammal.prototype 中,所有 MyMammal 实例都会参与它?
  • 没错,getName 可用于每个实例,并且每个实例都相同,并且只创建一次。仍然这种方式提供了更具可读性的代码:-)
猜你喜欢
  • 2014-11-26
  • 2011-03-12
  • 1970-01-01
  • 2018-02-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-07-20
  • 2015-02-01
相关资源
最近更新 更多