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

标签 javascript performance oop

更新

自从我提出这个问题以来,很多水都被淹没了,我已经改用模块模式和 CommonJS 文件格式 + Browserify并停止尝试让 Javascript 更像一种 OOP 语言。我已经接受了 Javascript 原型(prototype)继承和 Object.create,我的生活现在比以往任何时候都更好!,是的,几乎感觉我加入了一个新宗教,抱歉 宗教...在 JS 中对我来说不再有"new"了。

问题的其余部分只是历史......

<小时/>

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

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

我所采用的方法的缺点:

  1. 我需要一个虚拟类 Nexus(我真的不喜欢实例化基类的对象只是为了让继承链正常工作...... Nexus 可以解决问题)
  2. 我没有提供对正确设置上下文的重写方法的访问。消费者可以使用 call 或 apply 来更改上下文。

使用额外的 Nexus 虚拟函数来创建正确的原型(prototype)链是否会成为内存管理的问题?

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

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

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

最佳答案

Does having the extra Nexus dummy function to create the right prototype chain is an issue for memory management?

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

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

关于javascript - 在 javascript 中启用 OOP 的简单方法是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15013418/

相关文章:

python - 为什么 NumPy 有时比 NumPy + 普通 Python 循环慢?

c++ - 采用 N 个参数并返回 N 个值的高性能解决方案

c# - PHP 中的部分类就像我们在 C# 中一样

c# - 业务逻辑类的正确接口(interface)

javascript - jquery 复选框速度慢,不知道如何修复

Javascript 方法

scala - 函数式编程是否可以减少冯·诺依曼瓶颈?

__get 访问器上的 PHP empty()

javascript - 如何使用 AJAX 和 jQuery 正确检查包含 "/+=@#^"的密码

javascript - 预期声明但发现 '"显示 :none ;"' . 跳到下一个声明