题
我知道有很多类似的问题是很多很好的答案。我想看看在古典继承方法,或者这些封闭的方法等。不知何故我认为他们或多或少的"黑客"的方法对我来说,这真的没什么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#仿真要解释什么我想要做的:
class PARENT {
public PARENT (basevar) { ... }
}
class CHILD : PARENT {
public CHILD (basevar) : PARENT (basevar) // constructor of child, and call parent constructor during construct.
{ ... }
}
由于某些原因(如init。UI元),将它们放在构造,似乎最好的方式来做。任何人都有思想上我怎么可以这样做。
PS:在*1个,我不知道我应该放在那里。PS2:上述情况,我没有发现!继承库可以做的,我只是想知道如果不使用的图书馆可以实现这一目标。PS3:或者我的理解是错误的。由于javascript不是要证明面向对象(这就是为什么我叫它黑客),什么是"正确"的逻辑来实现这一点。
解决方案
它不是一个劈这样; JavaScript是一种原型的语言,通过维基百科如定义为其中:
..类不存在,和行为重用(被称为基于类的语言继承)通过克隆充当原型现有对象的过程被执行。
,因为它说,类不是在JavaScript中使用;您创建从JavaScript的Object
下降每个对象;在JavaScript中的所有对象都具有prototype
对象,对象的所有实例创建从他们的对象的原型对象“继承”的方法和属性。看看在MDC 原型对象更多的信息参考。
由于此,当调用行:
CHILDClass.prototype = new PARENTClass();
这允许CHILDClass
对象的方法和属性从PARENTClass
对象,它创建类似于存在于基于类的语言继承的想法的效果添加到它的原型对象。由于prototype
对象影响该对象的每个实例的,这允许父对象的方法和属性存在于你的子对象的每个实例。
如果你想打电话给你的父类的构造函数在子类的构造函数,您使用JavaScript call
功能;这使您可以调用父类的构造函数在子类的构造函数的情况下,因此你的子类的新原型属性设置为他们设置为在父类中。
您也不必把任何东西,你所指定的*1
,因为该行仅用于添加的方法和属性的子类的原型对象;但是,请记住,它调用父类的构造函数,所以如果有在父类的构造函数的操作基本任何参数,你应该检查,这些都存在,以避免JavaScript错误。
其他提示
JavaScript有没有内置用于继承层次支持类型扩展名应该是通过聚合进行,即直接加入期望的功能对象本身或它的原型,如果该属性将被实例之间共享。
然而,JS强大到足以使执行其他形式的对象构造的可能的,包括经典的继承。
给定一个克隆功能 - 这足以补充“真”原型继承,而不是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';
也有可能增加对基于类的继承了一些语法糖 - 我自己实施的可以这里找到。
从上面的例子将随后读
var ParentClass = Class.extend({
constructor: function(baseVar) {
// do stuff
},
a: 'b',
c: 'd'
});
var ChildClass = ParentClass.extend({
e: 'f'
});
我有一个轻质的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
可在源代码:类。 JS
我也有我的博客文章了解 OOP在JavaScript <详细信息/ p>
我只想提及的一些问题与经典的图案你会用于:
- 参考vars上的超级类(es)将可用作基本上是静态的所有实例。例如,如果你有var arr=[1、2、3的]在超级和做instance_1.区。推(4)instance_2.区。推动(5)所有这些实例中,将"见"的变化。
所以你解决1.与艾曼的解决方案,这Zakas呼吁"构造偷",但现在你打电话的构造两次:一旦您的原型和一次的构造偷窃。解决方案-你的原型使用一个助手像inheritPrototype(我表现出的整个执行这在这个员额: inheritPrototype方法 总的来说,这基本上来自一个组合的第181页的Zakas的书和一些Crockford研究。
没有隐私权(但是,再说,你需要使用类似持久的对象模式,获得这可能不是你想要的)
- 对象的定义被留"晃来晃去":解决方案-放的,如果声明检查对于任何原型的职能,并然后确定原型原型文字。
我已经运行的例子所有的这个上审查!!!
它已经一样多的一个挑战对我来说真正的神交:Zakas和Crockford书对象的创造和继承权。我也需要尝试一些不同的JavaScript TDD框架。所以我决定创建一篇关于这两个TDD框架和JavaScript对象的创建和继承权。它运行的代码和jspec测试!这里就是链接:* 我想开放源的文章/书