0

更新

自从我提出这个问题以来,河里已经流了很多水,我已经切换到使用模块模式和 CommonJS 文件格式 + Browserify并停止尝试使 Javascript 更像是一种 OOP 语言。我已经接受了 Javascript Prototypal Inheritance,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. Child obj 也是父类的实例以及子类的实例
  2. Child obj 可以调用父类的方法来访问覆盖的方法。(与 CurrentClass._parent 和 BaseClass.prototype 的唯一区别是,第二个要求类的使用者实际知道父类的名称,我想避免这种情况)。

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

我遵循的方法的缺点:

  1. 我需要一个虚拟类 Nexus(我真的不喜欢实例化基类的对象只是为了让继承链正常工作...... Nexus 做到了)
  2. 我没有提供对正确设置上下文的覆盖方法的访问。由消费者使用调用或应用来更改上下文。

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

我没有时间进行适当的测试,而且我的继承链不超过 3 级。所以那里的影响似乎很小。

我本来可以为此使用一个库,但是直接制作它似乎非常简单,并且仍然将一些代码放在构造函数中,我看不到使用额外的 init 类进行初始化的好处。

您认为添加虚拟 Nexus 功能会产生什么明显影响?

4

1 回答 1

2

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

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

但是,Nexus您应该只使用Object.create. 另请参阅了解 Crockford 的 Object.create shim

于 2013-02-21T22:39:45.860 回答