更新
自从我提出这个问题以来,河水已泛滥成灾,我切换到使用模块模式和CommonJS文件格式+ Browserify,并停止尝试使Javascript更像是一种OOP语言。我已经接受了Javascript原型继承和Object.create
,现在我的生活比以往任何时候都更好!是的,我几乎感觉就像我加入了new Religion
,对不起religion
...在JS中对我来说不再是“新”了。
剩下的问题只是历史...
我在javascript中玩了一段时间OOP。
老实说,我的感觉是大多数时候不需要真正的OOP。我以前在OOP中用其他语言来做的事情,大多数时候都可以使用javascript中的函数和闭包来完成。
此外,为了模仿OOP方法,有无数种方法可以使其手工制作或使用其中存在的小型库来实现。
我想尝试一下OOP,但是我发现的所有解决方案似乎都不那么简单,有人要求我添加一个init方法,或者在初始化过程中,他们正在对功能进行特殊检查以了解是否需要使用这些功能。覆盖。尽管这很聪明,但是对于从Class中简单地创建对象来说似乎有点多余。
所以我想到了这个解决方案:
更新:这是一个实验,无意替代任何出色的现有库或在生产中使用
var Nexus = function() {}; // helper function to avoid create an instance of the child class
Object._extend = function(child, parent) {
var base = Nexus.prototype = parent.prototype;
child.prototype = new Nexus();
var cp = child.prototype;
cp.constructor = child;
child._parent = base;
};
/* THIS THEN IS USED LIKE THIS */
var Person = function (name) {
this.name = name;
console.log('Person constructor');
};
$.extend(Person.prototype, {
walk : function () {
console.log(this.name + ' is Walking!!');
}
});
var Student = function () {
// call the base class constructor
Student._parent.constructor.apply(this, arguments);
console.log('Student Constructor');
}
Object._extend(Student, Person);
$.extend(Student.prototype, {
walk : function () {
console.log(this.name + ' walks like Student');
//calling a parent method
Student._parent.walk.apply(this, arguments);
}
});
var p = new Person('Jon Doe');
p.walk();
console.log(p instanceof Person) // true
var s = new Student('Joan Doe');
s.walk();
console.log(s instanceof Person) // true
console.log(s instanceof Student) // true
如您所见,这种方法满足了OOP的要求。
子obj也是父类的实例,也是子类的实例
子obj可以调用父类的方法来访问重写的方法。 (与CurrentClass._parent和BaseClass.prototype的唯一区别是,第二个要求类的使用者实际知道父类的名称,这是我想避免的)。
在这种情况下,创建构造函数必须很简单...函数本身就是构造函数。不需要简单的初始化方法...在实例化过程中会自动调用。
我遵循的方法的缺点:
我需要一个伪类Nexus(我真的不希望实例化基类的对象只是为了使继承链正常工作……Nexus可以解决问题)
在正确设置上下文的情况下,我没有提供对覆盖方法的访问。消费者可以通过调用或应用来更改上下文。
拥有额外的Nexus虚拟功能创建正确的原型链是否对内存管理有问题?
我没有时间进行适当的测试,并且我的继承链不超过3个层次。因此,影响似乎很小。
我本可以使用一个库,但是直接使其变得非常简单,并且仍将一些代码放入构造函数中,而我看不到拥有额外的初始化类进行初始化的好处。
您认为添加虚拟Nexus功能会有什么明显的影响?
最佳答案
拥有额外的Nexus虚拟功能创建正确的原型链是否对内存管理有问题?
不。您刚刚在内存中浮动了一个(一个!)附加对象。将其移到Object._extend
函数中,它甚至会自动进行垃圾收集。
但是,应该使用Nexus
代替该Object.create
东西。另请参见Understanding Crockford's Object.create shim。