我正在重写一个JavaScript项目,我希望能够使用面向对象的方法来组织当前代码的混乱。主要关注的是,这个JavaScript应该作为第三方网站中的一个小部件运行,我不能让它与其他网站可能使用的其他JavaScript库发生冲突。
因此,我正在寻找一种在JavaScript中编写“类”继承的方法,该继承具有以下要求:
super类型调用。最初,我尝试使用简单的原型链接:
function Shape(x,y) {
this.x = x;
this.y = y;
this.draw = function() {
throw new Error("Arbitrary shapes cannot be drawn");
}
}
function Square(x,y,side) {
this.x = x;
this.y = y;
this.side = side;
this.draw = function() {
gotoXY(this.x,this.y); lineTo(this.x+this.side, this.y); ...
}
}
Square.prototype = new Shape();这解决了需求1、2和6,但id不允许超级调用(新函数覆盖父函数),构造函数链接和动态扩展父类不向子类提供新方法。
欢迎提出任何建议。
发布于 2009-09-10 11:18:23
我建议使用函数从原型而不是实例继承以下模式:
function Shape(x, y) {
this.x = x;
this.y = y;
}
Shape.prototype.draw = function() {
throw new Error('Arbitrary shapes cannot be drawn');
};
function Square(x,y,side) {
Shape.call(this, x, y); // call super constructor
this.side = side;
}
// inherit from `Shape.prototype` and *not* an actual instance:
Square.prototype = clone(Shape.prototype);
// override `draw()` method
Square.prototype.draw = function() {
gotoXY(this.x,this.y); lineTo(this.x+this.side, this.y); // ...
};方法驻留在原型中是很重要的(因为性能方面的原因,它应该是这样的),所以您可以通过以下方式调用超类的方法
SuperClass.prototype.aMethod.call(this, arg1, arg2);使用一些句法糖,您可以使JS看起来像一种基于类的经典语言:
var Shape = Class.extend({
constructor : function(x, y) {
this.x = x;
this.y = y;
},
draw : function() {
throw new Error('Arbitrary shapes cannot be drawn');
}
});
var Square = Shape.extend({
constructor : function(x, y, side) {
Shape.call(this, x, y);
this.side = side
},
draw : function() {
gotoXY(this.x,this.y); lineTo(this.x+this.side, this.y); // ...
}
});发布于 2009-09-10 10:49:33
Douglas在Javascript中有关于古典主义和原型继承的优秀文章,这应该是一个很好的起点。
发布于 2009-09-10 12:44:33
好的,在JavaScript中复制类/实例样式系统的诀窍是,您只能在实例上使用原型继承。因此,您需要能够创建一个仅用于继承的“非实例”实例,并将初始化方法与构造函数本身分开。
这是我使用的最小系统(在添加花边之前),将一个特殊的一次性值传递给构造函数,让它在不初始化对象的情况下构造一个对象:
Function.prototype.subclass= function() {
var c= new Function(
'if (!(this instanceof arguments.callee)) throw(\'Constructor called without "new"\'); '+
'if (arguments[0]!==Function.prototype.subclass._FLAG && this._init) this._init.apply(this, arguments); '
);
if (this!==Object)
c.prototype= new this(Function.prototype.subclass._FLAG);
return c;
};
Function.prototype.subclass._FLAG= {};使用new Function()是避免在子类()上形成不必要的闭包的一种方法。如果您愿意,可以用更漂亮的function() {...}表达式替换它。
用法相对清晰,通常类似于Python样式的对象,但语法稍显笨拙:
var Shape= Object.subclass();
Shape.prototype._init= function(x, y) {
this.x= x;
this.y= y;
};
Shape.prototype.draw= function() {
throw new Error("Arbitrary shapes cannot be drawn");
};
var Square= Shape.subclass();
Square.prototype._init= function(x, y, side) {
Shape.prototype._init.call(this, x, y);
this.side= side;
};
Square.prototype.draw= function() {
gotoXY(this.x, this.y);
lineTo(this.x+this.side, this.y); // ...
};猴子修补一个内置的(功能)有点问题,但它让人愉快地阅读,而且没有人可能想要for...in的一个功能。
https://stackoverflow.com/questions/1404559
复制相似问题