我定义了两个函数如何相互继承,如下所示:
Function.prototype.inherit = function(parent){
function proto() {}
proto.prototype = parent.prototype;
this.prototype = new proto();
this.prototype.constructor = this;
this.prototype.parent = parent;
}
然后我需要定义一个isInstance函数,它的行为类似于Java的instanceOf或PHP的instanceof。实质上,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专家,我的代码是否有任何改进(可能是继承方法)?
感谢。
答案 0 :(得分:6)
然后我需要定义一个isInstance函数,它的行为类似于Java的instanceOf或PHP的instanceof。
JavaScript自己的instanceof
有什么问题?
鉴于你的继承功能,
function Shape() {};
function Square() {};
Square.inherit(Shape);
alert(new Square() instanceof Shape); // true
instanceof
通过检查给定构造函数的prototype
属性是否在实例的原型链中来工作。所以例如。
function A() {};
function B() {};
var b= new B();
A.prototype= B.prototype;
alert(b instanceof A); // true
即使instanceof Shape
未使用Square.prototype
创建new Shape
,这也是new proto()
有效的原因。相反,它是由proto
创建的,但由于Shape
和prototype
共享相同的__proto__
属性,因此JavaScript无法区分。
您通常无法看到原型链(虽然Firefox和WebKit通过new
属性使其可用),但它是实际在JS中处理继承的方式;可见的Function.prototype属性仅用于在Object.prototype.isInstance(c)= function() {
return this instanceof c;
}
- 时间设置原型链的初始状态。
如何将isInstance添加到实例中,而不仅仅是函数?
instanceof
我不确定这真的会让你受益匪浅!对Object进行原型设计通常被认为是不好的,因为它会影响每个对象,并且可能会使用Object将其他脚本混淆为查找映射。
我的代码是否有任何改进(可能是继承方法)?
我喜欢你的继承方法,它是制作对象系统的一种更轻量级的JavaScripty方法。
使用parent
,您可能会丢失constructor
和parent
属性,除非您出于其他方便目的而想要它们。我将constructor
放在构造函数上(所以它就像知道它的基类的子类),我会调用constructor
其他东西(已经有一个名为function Square() {
Shape.apply(this, arguments);
}
Square.inherit(Shape);
的属性在Firefox中但它没有按照您的想法进行,通常最好避免使用。)
我看到的唯一缺点是你不能继承构造函数,所以每次你创建一个新的子类时,你必须编写一个调用基本构造函数的构造函数,即使你的子类的构造函数什么都不做:
{{1}}
答案 1 :(得分:4)
你为什么需要这样做?由于某种原因,JavaScript没有严格的类层次结构的概念:它确实无法完成。你可以找到一个大部分时间都可以工作的解决方案,但我不确定你是否可以覆盖所有边缘情况。此外,由于JavaScript没有任何接口概念,因此对显式继承的测试会导致高耦合,并且似乎违反了SOLID principles。
使用duck typing是一种更好(更惯用)的方法来解决这个问题。只需测试您需要的方法的存在,然后调用它。只要准备好在必要时捕获异常(无论如何你都应该这样做)。
答案 2 :(得分:1)
要将好的设计论点搁置一秒钟并专注于您的问题,问题是您将isInstance()
设置为Function
原型的方法。这意味着Function
的对象将拥有它,而不是的对象(例如示例中的Object1
和Object2
)则不会。
我建议不要试图将它作为一种方法来实现,而是让它成为一个静态函数:
function isInstance(object, ofClass) {
// Same logic as you have, except use
// object.prototype instead of this.prototype
}
然后您可以将其作为
调用isInstance(obj2, Object2);