很长一段时间以来,我一直在兜售使我的JavaScript更面向对象的想法。我也看过几个不同的实现,但我只是不能决定它是否必要。
我想回答的是以下问题
发布于 2010-09-28 22:45:08
哈。在我看来,它看起来比需要的复杂得多。
实际上,更仔细地看,我真的反对它在方法中提供this._super()的做法,即调用超类方法。
代码引入了对typeof==='function' (某些对象不可靠)、Function#toString (argh,函数分解也不可靠)的依赖,并根据是否在函数体中使用了字节_super序列来决定是否包装(即使您只在字符串中使用过它)。如果你试一试。this['_'+'super'],它会失败的)。
如果要在函数对象上存储属性(例如MyClass.myFunction.SOME_PRIVATE_CONSTANT,这可能是为了保持名称空间的清洁),则包装将阻止您获取这些属性。如果在方法中抛出异常,并在同一对象的另一个方法中捕获异常,_super将最终指向错误的东西。
所有这些只是为了让调用超类的同名方法变得更容易。但我不认为这在JS中特别难做。这对自己来说太聪明了,而且在这个过程中使整个过程变得不那么可靠。(哦,而且arguments.callee在严格模式下是无效的,尽管这并不是他的错,因为这是在他发布后发生的。)
这是我现在用来上课的东西。我并不认为这是“最好”的JS类系统,因为有很多不同的方法可以实现,还有很多不同的特性需要添加或不添加。但是它非常轻量级,它的目标是成为‘JavaScriptic’,如果这是一个词的话。(事实并非如此。)
Function.prototype.makeSubclass= function() {
function Class() {
if (!(this instanceof Class))
throw 'Constructor function requires new operator';
if ('_init' in this)
this._init.apply(this, arguments);
}
if (this!==Object) {
Function.prototype.makeSubclass.nonconstructor.prototype= this.prototype;
Class.prototype= new Function.prototype.makeSubclass.nonconstructor();
}
return Class;
};
Function.prototype.makeSubclass.nonconstructor= function() {};它规定:
new。另一种方法是静默地将X()重定向到new X(),这样缺少的new就能工作。这是一个最好的选择;我选择了显式错误,这样一个人就不会习惯在没有new的情况下写作,并在其他没有这样定义的对象上造成问题。这两种方法都比不能接受的JS默认设置要好,即让this.属性落入window,然后神秘地出错。_init方法,因此您不必编写只调用超类构造函数的构造函数。仅此而已。
下面是如何使用它实现Resig的示例:
var Person= Object.makeSubclass();
Person.prototype._init= function(isDancing) {
this.dancing= isDancing;
};
Person.prototype.dance= function() {
return this.dancing;
};
var Ninja = Person.makeSubclass();
Ninja.prototype._init= function() {
Person.prototype._init.call(this, false);
};
Ninja.prototype.swingSword= function() {
return true;
};
var p= new Person(true);
p.dance(); // => true
var n = new Ninja();
n.dance(); // => false
n.swingSword(); // => true
// Should all be true
p instanceof Person &&
n instanceof Ninja && n instanceof Person超类调用是通过专门命名所需的方法并对其进行call来完成的,有点像在Python中那样。如果您想避免再次命名_super,可以向构造函数添加一个Person成员(所以您可以说是Ninja._super.prototype._init.call,或者是Ninja._base._init.call)。
发布于 2010-09-29 04:35:02
JavaScript是基于原型的而不是基于类的。我的建议是不要用JS方式声明子类型:
MyDerivedObj.prototype = new MySuperObj();
MyDerivedObj.prototype.constructor = MyDerivedObj;发布于 2010-09-29 09:20:11
看看在不使用继承的情况下可以走多远。将其视为一种性能攻击(在真正需要的地方勉强应用),而不是一种设计原则。
在像JS这样的高度动态的语言中,很少有必要知道对象是否是Person。您只需要知道它是否具有firstName属性或eatFood方法。您通常不需要知道一个对象是否是一个数组;如果它有一个length属性和一些以整数命名的其他属性,那通常就足够好了(例如,参数对象)。“如果它像鸭子一样走路,像鸭子一样嘎嘎叫,那就是鸭子。”
// give back a duck
return {
walk: function() { ... },
quack: function() { ... }
};是的,如果您正在制造大量的小对象,每个对象都有几十个方法,那么无论如何都要将这些方法分配给原型,以避免在每个实例中创建数十个插槽的开销。但将此视为减少内存开销的一种方法--仅仅是一种优化。并帮助用户将new的使用隐藏在某种工厂函数的后面,这样他们甚至不需要知道对象是如何创建的。他们只需要知道它有方法foo或属性bar。
(请注意,在这种情况下,您不会真正建模古典继承。它仅仅相当于定义一个类来获得共享vtable的效率。)
https://stackoverflow.com/questions/3817409
复制相似问题