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

时间:2013-02-21 22:25:28

标签: javascript performance oop

更新

由于我提出了这个问题,河水已经流了很多水,我已经切换到使用模块模式和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. 创建构造函数必须简单,在这种情况下......函数本身就是构造函数。不需要在实例化期间自动调用的简单init方法。

  4. 我遵循的方法中的缺点:

    1. 我需要一个虚拟类Nexus(我真的不想实例化基类的对象只是为了让继承链正常工作...... Nexus可以做到这一点)
    2. 我没有正确设置上下文提供对重写方法的访问权限。消费者可以使用call或apply来更改上下文。
    3. 是否有额外的Nexus虚拟功能来创建正确的原型链是内存管理的问题?

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

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

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

1 个答案:

答案 0 :(得分:2)

  

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

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

但是,您应该使用Object.create而不是Nexus。另请参阅Understanding Crockford's Object.create shim