我定义两个函数如何相互继承,如下所示:
Function.prototype.inherit = function(parent){
function proto() {}
proto.prototype = parent.prototype;
this.prototype = new proto();
this.prototype.constructor = this;
this.prototype.parent = parent; }
然后,我需要定义一个行为类似于Java的instanceof或PHP的instanceOf的isInstance函数。本质上,isInstance可用于确定变量是否为继承自父函数的函数的实例化对象。
这是我写的:
Function.prototype.isInstance = function(func){
if(this == func){
return true;
} else{
if (this.prototype.parent == undefined || this.prototype.parent == null) {
return false;
} else {
return this.prototype.parent.isInstance(func);
}
}}
这在比较两个函数时工作得很好,但在比较实例化的变量时就不行了。
Object2.inherit(Object1);
Object2.isInstance(Object1); //returns true
var obj2 = new Object2();
obj2.isInstance(Object1);// obj2.isInstance is not a function上面的最后一个例子就是我想要的。如何将isInstance添加到实例,而不仅仅是函数?对于所有javascript专家来说,我的代码(也许是inherit方法)有什么改进吗?
谢谢。
发布于 2009-10-03 17:32:09
然后我需要定义一个isInstance函数,它的行为类似于Java的instanceof或PHP的instanceOf。
JavaScript自己的instanceof有什么问题?
根据您的继承函数,
function Shape() {};
function Square() {};
Square.inherit(Shape);
alert(new Square() instanceof Shape); // trueinstanceof的工作原理是检查给定构造函数的prototype属性是否在实例的原型链中。所以,例如。
function A() {};
function B() {};
var b= new B();
A.prototype= B.prototype;
alert(b instanceof A); // true这就是为什么即使Square.prototype不是使用new Shape创建的,instanceof Shape仍然可以工作;相反,它是由new proto()创建的,但是由于proto和Shape共享相同的prototype属性,所以JavaScript无法区分它们。
您通常看不到原型链(尽管Firefox和WebKit通过__proto__属性提供了它),但它是JS中实际处理继承的方式;visible Function.prototype属性仅用于在new-time中设置原型链的初始状态。
如何将isInstance添加到实例,而不仅仅是函数?
Object.prototype.isInstance(c)= function() {
return this instanceof c;
}不过,我不确定这对你有多大帮助!而对象的原型设计通常被认为是低级的,因为它会影响每个对象,并且可能会混淆使用Object进行查找映射的其他脚本。
我的代码(也许是inherit方法)有什么改进吗?
我喜欢你的inherit方法,它是创建对象系统的一种更轻量级的JavaScripty方法。
使用instanceof,您可能会丢失parent和constructor属性,除非您出于其他方便的目的而需要它们。我会把parent放在构造函数上(所以它就像一个知道它的基类的子类),我会调用constructor来做其他事情(火狐中已经有一个名为constructor的属性,但它不会做你想的那样,通常最好避免)。
我看到的唯一缺点是你不能继承构造函数,所以每次你创建一个新的子类,你必须编写一个调用基本构造函数的构造函数,即使你的子类的构造函数什么也不做:
function Square() {
Shape.apply(this, arguments);
}
Square.inherit(Shape);发布于 2009-10-03 16:18:48
为什么需要这样做?JavaScript没有严格的类层次结构的概念是有原因的:它真的不能做到。您可能会得到一个在大多数情况下都有效的解决方案,但我不确定您是否能涵盖所有边缘情况。此外,由于JavaScript没有任何接口的概念,因此测试显式继承会导致高度耦合,并且似乎违反了SOLID principles。
解决这个问题的一种更好(也更惯用)的方法是使用duck typing。只需测试所需方法的存在,然后调用它。做好必要时捕获异常的准备(无论如何你都应该这样做)。
发布于 2009-10-03 16:52:55
把好的设计论点放在一边,专注于你的问题,问题是你在Function的原型上将isInstance()设置为一个方法,这意味着是Function的对象将会有它,而没有的对象(比如你例子中的Object1和Object2 )将不会有它。
我建议将其作为一个方法来实现,而不是将其作为一个静态函数来实现:
function isInstance(object, ofClass) {
// Same logic as you have, except use
// object.prototype instead of this.prototype
}然后,您可以像这样调用它
isInstance(obj2, Object2);https://stackoverflow.com/questions/1514151
复制相似问题