在javascript中启用OOP的简单方法是什么

What is the simple approach to enable OOP in javascript?

本文关键字:简单 方法 是什么 OOP javascript 启用      更新时间:2023-09-26

更新

自从我提出这个问题以来,很多水都流到了河里,我不得不改用模块模式和CommonJS文件格式+Browserify,并停止尝试让Javascript更像OOP语言。我接受了Javascript原型继承和Object.create,我的生活比以往任何时候都好!,是的,几乎感觉我加入了new Religion,对不起,religion。。。JS中再也没有"新"了。

剩下的问题只是历史。。。


我在javascript中玩OOP已经有一段时间了。

老实说,我的感觉是,大多数时候都不需要真正的OOP。我在其他语言中使用OOP所做的事情,大多数时候都可以用javascript中的函数和闭包来完成。

此外,为了模仿OOP方法,有很多方法可以让它手工制作或使用现有的小型库。

我想尝试一下OOP,但我发现的所有解决方案似乎都不那么简单,有些人要求我添加一个init方法,或者在初始化过程中,他们正在对函数进行特殊检查,以确定是否需要重写它们。虽然这很聪明,但对于简单地从类创建对象来说似乎有点过分。

所以我提出了这个解决方案:

更新:这是一个实验,不打算取代任何出色的现有库或用于生产

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. 子对象也是父类的实例,也是子类的实例
  2. Child对象可以调用父类的方法来访问重写的方法。(与CurrentClass_parent和BaseClass.prototype的唯一区别是,第二个要求类的使用者实际知道父类的名称,我想避免这样做)。

  3. 创建构造函数必须很简单,在这种情况下。。。函数本身就是构造函数。不需要简单的init方法。。。在实例化期间自动调用。

我采用的方法的缺点:

  1. 我需要一个伪类Nexus(我真的不喜欢实例化基类的对象,只是为了让继承链正常工作…Nexus做到了)
  2. 在上下文设置正确的情况下,我没有提供对重写方法的访问权限。由使用者使用调用或应用来更改上下文

拥有额外的Nexus虚拟功能来创建正确的原型链是否是内存管理的问题

我还没有时间进行适当的测试,我的继承链不超过3个级别。因此,那里的影响似乎很小。

我本可以使用一个库来实现这一点,但直接制作它并在构造函数中放入一些代码似乎非常简单,我看不到有一个额外的init类用于初始化的好处。

你认为增加虚拟Nexus功能会产生什么明显的影响?

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

没有。你刚刚有一个(一个!)额外的对象在内存中浮动。将它移到Object._extend函数中,它甚至会自动进行垃圾回收。

但是,您应该使用Object.create,而不是Nexus。另请参阅理解Crockford';s对象。创建填充程序。