我长期浏览stackoverflow,但第一次参与。如果我错过了任何礼节细节,请告诉我!
此外,我已经搜遍了高低之处,包括这个网站,但我没有找到一个清晰简洁的解释,能够明确我正在寻找的内容。如果我只是错过了它,请指引我正确的方向!
好的,我想扩展一些本地JavaScript对象,比如Array和String。然而,我不想实际扩展它们,而是创建从中继承的新对象,然后修改这些对象。
对于Array,这样做是有效的:
var myArray = function (n){
this.push(n);
this.a = function (){
alert(this[0]);
};
}
myArray.prototype = Array.prototype;
var x = new myArray("foo");
x.a();
然而,对于String类型,这种方法不起作用:
var myString = function (n){
this = n;
this.a = function (){
alert(this);
};
}
myString.prototype = String.prototype;
var x = new myString("foo");
x.a();
我也尝试过:
myString.prototype = new String();
现在,在尝试研究这个问题时,我发现以下代码可以正常工作:
var myString = function (n){
var s = new String(n);
s.a = function (){
alert(this);
};
return s;
}
var x = myString("foo");
x.a();
然而,这对我来说几乎感觉像是“作弊”。就像,我应该使用“真正”的继承模型,而不是这个快捷方式。所以,我的问题是:
1)您能告诉我从String继承方面我做错了什么吗?(最好附上一个可行的示例...)
2)在“真正”的继承示例和“捷径”示例之间,您能否列举任何一种方法比另一种方法更具明显的优点或劣势?或者只是在功能上有些差异?(因为它们最终看起来都是一样的...)
谢谢大家!
编辑:
感谢所有评论/回答。我认为@CMS的信息是最好的,因为:
1)他通过指出在自己的字符串对象中部分重新定义String可以使其正常工作来回答了我的String继承问题。(例如覆盖toString和toValue) 2)从Array继承的新对象具有自己的限制,这些限制并不立即可见,也无法通过部分重新定义Array来解决。
从上述2点出发,我得出结论:JavaScript的可继承性声称仅适用于您自己创建的对象,并且当涉及到原生对象时,整个模型会崩溃。(这可能是为什么你找到的90%的例子都是Pet->Dog或Human->Student,而不是String->SuperString)。这可以通过@chjj的答案来解释,这些对象实际上应该是原始值,尽管JS中的所有内容似乎都是对象,并且应该是100%可继承的。
如果这个结论完全错误,请更正我。如果它是准确的,那么我相信这对任何人来说都不是新闻 - 但再次感谢您所有的评论。我想我现在有一个选择:
要么继续使用寄生继承(我现在知道的第二个示例名称),并尝试减少其可能的内存使用影响,要么像@davin、@Jeff或@chjj建议的那样为自己假定义或完全重新定义这些对象(这似乎是一种浪费)。
@CMS-将您的信息编译成答案,我会选择它。
length
属性不会自动更新,并且当你给它赋值时,它不会影响对象的其他属性(例如x.length = 0; //空数组
)。这比看起来更加复杂。请查看这篇文章。 - Christian C. SalvadóString.prototype
添加方法)而不是对其进行子类化。现在经常使用此方法作为polyfill来使新方法与旧实现兼容,并且还可以用于创建自己的方法(具有命名空间冲突注意事项)。 - jfriend00