2013-02-21 65 views
0

UPDATE什么是在JavaScript中启用OOP的简单方法?

自从我提出这个问题,大量的水已经下溪走了,我必须切换到使用模块模式和CommonJS的文件格式+ Browserify并停止试图让JavaScript脚本更像是一个面向对象的语言。我接受了Javascript Prototypal Inheritance和Object.create,我的生活现在比以往更好!,是的,几乎感觉就像我加入了new Religion,对不起religion ......对于我来说,再也没有JS的“新”了。

问题的其余的就是历史...


我已经是与OOP玩弄于JavaScript的一段时间。

老实说,我的感觉是,大部分时间真正的OOP是不需要的。在OOP中我曾经用其他语言做过的事情,大部分时间都可以在javascript中用函数和闭包完成。

同样为了模仿OOP方法,有很多方法可以让它通过手工或使用一个小型的库发现。

我想尝试一下OOP,但是我发现的所有解决方案在我看来都不那么简单,有些要求我添加一个init方法,或者在初始化期间他们正在对函数进行特殊检查以了解是否他们需要被覆盖。虽然这很聪明,但从简单的Class创建一个对象似乎有点过分。

于是我想出了这个解决方案:

UPDATE:这个实验,无意取代任何辉煌退出库或生产

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的要求。

  1. 一个孩子obj是一个父类的实例,也还有子类
  2. 一个孩子obj的实例可以调用父类的方法来访问覆盖的方法。 (与CurrentClass._parent和BaseClass.prototype唯一的不同之处在于第二个需要类的使用者真正知道父类的名称,这是我想避免的)。

  3. 创建构造函数必须简单,在这种情况下...函数本身就是构造函数。不需要简单的初始化方法...在实例化过程中被自动调用。

在方法的缺点我也跟着:

  1. 我需要一个虚拟类的Nexus(我真的不喜欢实例化基类的对象只得到继承链正常工作... Nexus做的伎俩)
  2. 我没有提供访问重写的方法,正确设置上下文。消费者可以使用呼叫或应用来更改上下文。

是否有额外的Nexus虚拟函数来创建正确的原型链是内存管理的一个问题?

我没有时间做适当的测试,而且我的继承链并不比3级更深。所以这里的影响似乎非常小。

我可能正在使用一个库,但它似乎非常简单,直接做,并仍然在构造函数中,我没有看到从初始化的额外init类的好处看到它的好处。

您认为添加虚拟Nexus功能有什么显着的影响?

+1

在我看来,你对OOP for JavaScript的直观感觉有些不恰当是正确的。 – Pointy 2013-02-21 22:27:00

+0

是的,我作为一个实验做得比实际使用更多。这就是我问的原因。感谢您的反馈 – 2013-02-21 22:29:25

+0

@Point和OP谢谢!最后,有些人不会认为JavaScript是OOP,因为它不是,它只是在玩范围。如果您需要隐藏数据,请使用模块模式,不要发疯! – defaultNINJA 2013-02-21 22:30:08

回答

2

是否有额外的Nexus虚拟函数来创建正确的原型链是内存管理的问题?

不,你刚刚在内存中有一个(一个!)附加对象。将它移动到Object._extend函数中,它甚至会自动收集垃圾。

但是,而不是那Nexus事情你应该只使用Object.create。另见Understanding Crockford's Object.create shim

+0

感谢您的反馈,并明确地尝试Object.create shim – 2013-02-21 22:42:12

+0

对于实验,您不会需要填充它:-)只是链接,以帮助理解你的代码为什么工作。另请参阅http://stackoverflow.com/q/4166616/1048572和http://stackoverflow.com/q/2709612/1048572 – Bergi 2013-02-21 22:45:16

+0

object.create是否刚创建一个新的对象?所以它不像是从预定义的类创建一个新的对象。无论如何,我很难说我需要超过3级的继承。 – 2013-02-21 22:52:44

相关问题