代码之家  ›  专栏  ›  技术社区  ›  xandy

javascript继承

  •  8
  • xandy  · 技术社区  · 17 年前

    我知道有很多类似的问题,有很多很好的答案。我试图看看经典的继承方法,或者那些封闭方法等等。我认为它们或多或少是对我的“黑客”方法,因为它并不是真正的JavaScript设计要做的。(如果我错了,欢迎任何人纠正我)。

    PARENTClass = function (basevar) { do something here; };
    PARENTClass.prototype = { a: b, c: d}; // prototype is auto gen 
    
    // Inheritance goes here
    CHILDClass = function (childvar) { do something; };
    CHILDClass.prototype = new PARENTClass(*1); // Actual inheritance to the prototype statement
    // Instance
    CHILDInstance = new CHILDClass(whatever);
    

    在某种程度上,我理解了JS的继承性。但有一个场景我不知道如何实现,那就是如果我想在对象创建期间(即在构造函数中)进行一些初始化,并且可以立即使用新对象,该怎么办。。。。我对这个问题的说明可能不太清楚,所以让我用下面的C#Psuedo来解释我想做什么:

    class PARENT {
        public PARENT (basevar) { ... }
    }
    class CHILD : PARENT {
        public CHILD (basevar) : PARENT (basevar) // constructor of child, and call parent constructor during construct.
        { ... }
    }
    

    出于某种原因(比如init.UI元素),将它们放入构造函数似乎是最好的方法。任何人都知道我该怎么做。

    附言:在*1中,我不知道应该放什么。 PS3:或者我的理解是错误的。既然javascript并不打算模仿OOP(这就是为什么我称之为hack),那么实现这一点的“正确”逻辑是什么。

    5 回复  |  直到 17 年前
        1
  •  17
  •   Alex Rozanski    17 年前

    这不是一个问题 乱劈 像这样的JavaScript是一种原型语言,由 Wikipedia 其中:

    …类不存在,行为重用(在基于类的语言中称为继承)是通过克隆作为原型的现有对象的过程来执行的。

    正如它所说的,JavaScript中不使用类;您创建的每个对象都是JavaScript的后代 Object ; JavaScript中的所有对象都具有 prototype 对象,以及您创建的对象的所有实例从其对象的原型对象“继承”方法和属性。看看MDC prototype

    至此,当您拨打电话时:

    CHILDClass.prototype = new PARENTClass();
    

    这允许 CHILDClass 对象从中向其原型对象添加方法和属性 PARENTClass 对象,它创建的效果类似于基于类的语言中存在的继承思想。自从 原型

    如果要在子类的构造函数中调用父类的构造函数,可以使用JavaScript call 作用这允许您在子类的构造函数的上下文中调用父类的构造函数,从而将子类中新的原型属性设置为在父类中设置的属性。

    您也不需要在指定的位置放置任何内容 *1 ,因为该行仅用于向子类的原型对象添加方法和属性;但是,请记住,它调用父类的构造函数,因此如果在父类构造函数的操作中有任何基本参数,您应该检查这些参数是否存在,以避免JavaScript错误。

        2
  •  10
  •   Ayman Hourieh    17 年前

    CHILDClass = function (basevar) {
      PARENTClass.call(this, basevar);
      // do something;
    };
    

    这里的诀窍是使用 call the documentation of call 更多细节。

        3
  •  1
  •   Christoph    17 年前

    JavaScript对继承层次结构没有内置支持,因为类型扩展应该通过聚合来完成,即如果属性要在实例之间共享,则直接向对象本身或其原型添加所需的功能。

    尽管如此,JS的强大功能足以实现其他形式的对象构造,包括经典继承。

    给予 clone function -这足以添加“真正的”原型继承,而不是JavaScript的巴斯德化——您的exampe可以这样实现:

    function ParentClass(baseVar) {
        // do stuff
    }
    
    // don't overwrite the prototype object if you want to keep `constructor`
    // see http://joost.zeekat.nl/constructors-considered-mildly-confusing.html
    ParentClass.prototype.a = 'b';
    ParentClass.prototype.c = 'd';
    
    function ChildClass(childVar) {
        // call the super constructor
        ParentClass.call(this, childVar);
    }
    
    // don't inherit from a ParentClass instance, but the actual prototype
    ChildClass.prototype = clone(ParentClass.prototype);
    ChildClass.prototype.e = 'f';
    

    也可以为基于类的继承(我自己的实现)添加一些语法糖 can be found here .

    上面的例子如下:

    var ParentClass = Class.extend({
        constructor: function(baseVar) {
            // do stuff
        },
        a: 'b',
        c: 'd'
    });
    
    var ChildClass = ParentClass.extend({
        e: 'f'
    });
    
        4
  •  1
  •   mythz    17 年前

    我有一个轻量级javascript OOP包装器,它提供了“类”继承,您可以重写基方法或调用基构造函数或成员。

    您可以这样定义类:

    //Define the 'Cat' class
    function Cat(catType, firstName, lastName)
    {
        //Call the 'Animal' constructor.
        Cat.$baseNew.call(this, firstName, lastName);
    
        this.catType = catType;
    }
    //Extend Animal, and Register the 'Cat' type.
    Cat.extend(Animal, { type: 'Cat' }, {
        hello: function(text)
        {
            return "meaoow: " + text;
        },
        getFullName: function()
        {
            //Call the base 'Animal' getFullName method.
            return this.catType + ": " + Cat.$base.getFullName.call(this);
        }
    })
    
    //It has a built-in type system that lets you do stuff like:
    
    var cat = new Cat("ginger", "kitty", "kat");
    Cat.getType()                     // "Cat"
    cat.getBaseTypesAndSelf()         // ["Cat","Animal","Class"]
    cat.getType()                     // "Cat"
    cat.isTypeOf(Animal.getType())    // "True"
    
    var dynamicCat = Class.createNew("Cat", ["tab","fat","cat"])
    dynamicCat.getBaseTypesAndSelf()  // ["Cat","Animal","Class"]
    dynamicCat.getFullName()          // tab: fat cat
    

    源代码可从以下网址获得: Class.js

    我在我的博客文章中也有关于 OOP in javascript

        5
  •  1
  •   Community Mohan Dere    9 年前

    我想我会提到一些你想要的经典模式的问题:

    1. 超类上的引用变量在所有实例上基本上都是静态的。例如,如果您在super中有var arr=[1,2,3],并且执行instance_1.arr.push(4)instance_2.arr.push(5),那么所有这些实例都将“看到”更改。
    2. 所以你解1。使用Ayman的解决方案,Zakas称之为“构造函数窃取”,但现在您调用构造函数两次:一次用于原型,一次用于构造函数窃取。解决方案-对于您的原型,请使用类似于inheritPrototype的帮助器(我在本文中展示了该原型的整个实现: inheritPrototype method FWIW,这基本上来自于Zakas书的181页和一些Crockford研究的结合。

    3. 没有隐私(但话说回来,您需要使用持久对象模式之类的东西来实现这一点,而这可能不是您想要的)

    我已经在github上运行了所有这些的示例!!!

    My GitHub Open Source Essay/Book