【发布时间】:2011-08-11 07:23:48
【问题描述】:
我将在秋季参加我的第一堂 OOP 课程(学习 Java),所以我一直在阅读有关它的内容,并通过一些关于语言的介绍来在上学前熟悉自己。我对学习 Java 感到非常兴奋,但我对 JavaScript 感觉更“自在”。我已经用它完成了一些项目,并且正在努力通过在 JS 中使用 OOP 将我的代码提升到下一个更专业的水平(如果你想说的话)。
目前我正在研究拖动脚本,并通过程序编程将其固定下来。由于这个项目在我的记忆中很新鲜,所以我从这个项目开始,开始转向对象。让我在这里绊倒的是拥有一个“拖动”对象的想法。 . .
function Drag() {
/* Drag code goes here */
} // constructor
我对 OOP 的想法相当了解,但这让我很困惑。在我经历过的所有例子中,对象总是,嗯,对象。它们是动物或汽车,或自行车等。我还没有遇到行为的对象。我只是不确定它是如何工作的。 . .如果您对此有任何建议,我将不胜感激。
现在继承!我还没有必要使用继承,但是这个主题让我对 JavaScript 感兴趣,因为很多人都为此付出了 2 美分。不过,我认为最流行的方式是John Resig's 和Douglas Crockford's 继承方式。
我认为它们是非常简洁的解决方法,但出于某种原因,我不太喜欢它们都需要分配。我想我只是觉得他们不应该那样工作。因此,在查看了更多示例和 Crockford 的方法之后,我想出了这个(非常抱歉,如果其他人已经有,我只是没见过):
Object.prototype.extend = function (Obj) {
'use strict'; // for jslint
this.prototype = new Obj();
this.prototype.constructor = this;
return this;
}
这是一个使用中的例子,我从here偷了例子然后稍微修改了一下:
Object.prototype.inObj = 1;
function A() {
'use strict';
this.inA = 2;
}
A.prototype.inAProto = 3;
function B() {
'use strict';
this.inB = 4;
}
/*** HERE IT IS ***/
B.extend(A);
B.prototype.inBProto = 5;
var w = new A();
var x = new B();
document.body.innerHTML = x.inObj + ', ' + x.inA + ', ' + x.inAProto + ', ' + x.inB + ', ' + x.inBProto; // 1, 2, 3, 4, 5
document.body.innerHTML += '<br />';
document.body.innerHTML += w instanceof A && w instanceof Object && x instanceof B && x instanceof A && x instanceof Object; // true
对我来说,它在语法上看起来和感觉都很好,我想知道经验丰富的 JS 开发人员会如何看待它。我对其进行了测试,我知道您可以将 B.extend(A) 放在 B 的定义之前,但不能将其放在 B.prototype.inBProto 之后,否则列表将变为 1、2、3、4,未定义,因为在 extend方法,B 的原型正在被重置。我正在努力解决这个问题,但我觉得B.extend(A) 无论如何都应该直接出现在构造函数的定义之后。
大家怎么看这种方式?提前致谢!
编辑:我开发了一个 [笨拙] 解决方法,它基本上采用继承对象原型的所有属性,然后在被新对象擦除干净后将它们重新添加:
Object.prototype.extend = function (Obj) {
'use strict';
var proto, p;
proto = {};
for (p in this.prototype) {
if (this.prototype.hasOwnProperty(p)) {
proto[p] = this.prototype[p];
}
}
this.prototype = new Obj();
this.prototype.constructor = this;
for (p in proto) {
if (proto.hasOwnProperty(p)) {
this.prototype[p] = proto[p];
}
}
return this;
};
谁知道呢,也许你不会认为这像我一样笨拙,但它确实有效,而且我认为它很酷! :D
【问题讨论】:
-
强烈建议不要扩充 Object.prototype,因为它可能会破坏(第三方)代码。我目前正在写一本关于 JavaScript 面向对象和继承的入门书。你可能会感兴趣,不过,我还需要几天时间,因为我是在业余时间做的。
-
@Daniel Baulig Aw,开枪。我想你是对的,虽然我不完全确定如何。我不明白为什么它会破坏其他代码。 . .
-
也同意@Daniel,但如果你想扩展对象,你不妨包括“defineGetter”和“defineSetter " 到对象属性。 :)
-
defineGetter 和 defineSetter 在较新版本的 JavaScript 中已弃用。新方式是:developer.mozilla.org/en/JavaScript/Reference/Global_Objects/…
-
查看 jOOPL,我创建的一个面向对象的编程基础,它是完全开源的,使用 Apache v2 许可证:joopl.codeplex.com
标签: javascript oop inheritance