首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在Javascript中实现isInstance

在Javascript中实现isInstance
EN

Stack Overflow用户
提问于 2009-10-03 16:05:59
回答 3查看 2.5K关注 0票数 0

我定义两个函数如何相互继承,如下所示:

代码语言:javascript
复制
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可用于确定变量是否为继承自父函数的函数的实例化对象。

这是我写的:

代码语言:javascript
复制
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);          
    }
}

}

这在比较两个函数时工作得很好,但在比较实例化的变量时就不行了。

代码语言:javascript
复制
Object2.inherit(Object1);

Object2.isInstance(Object1); //returns true

var obj2 = new Object2();

obj2.isInstance(Object1);// obj2.isInstance is not a function

上面的最后一个例子就是我想要的。如何将isInstance添加到实例,而不仅仅是函数?对于所有javascript专家来说,我的代码(也许是inherit方法)有什么改进吗?

谢谢。

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2009-10-03 17:32:09

然后我需要定义一个isInstance函数,它的行为类似于Java的instanceof或PHP的instanceOf。

JavaScript自己的instanceof有什么问题?

根据您的继承函数,

代码语言:javascript
复制
function Shape() {};
function Square() {};
Square.inherit(Shape);
alert(new Square() instanceof Shape); // true

instanceof的工作原理是检查给定构造函数的prototype属性是否在实例的原型链中。所以,例如。

代码语言:javascript
复制
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()创建的,但是由于protoShape共享相同的prototype属性,所以JavaScript无法区分它们。

您通常看不到原型链(尽管Firefox和WebKit通过__proto__属性提供了它),但它是JS中实际处理继承的方式;visible Function.prototype属性仅用于在new-time中设置原型链的初始状态。

如何将isInstance添加到实例,而不仅仅是函数?

代码语言:javascript
复制
Object.prototype.isInstance(c)= function() {
    return this instanceof c;
}

不过,我不确定这对你有多大帮助!而对象的原型设计通常被认为是低级的,因为它会影响每个对象,并且可能会混淆使用Object进行查找映射的其他脚本。

我的代码(也许是inherit方法)有什么改进吗?

我喜欢你的inherit方法,它是创建对象系统的一种更轻量级的JavaScripty方法。

使用instanceof,您可能会丢失parentconstructor属性,除非您出于其他方便的目的而需要它们。我会把parent放在构造函数上(所以它就像一个知道它的基类的子类),我会调用constructor来做其他事情(火狐中已经有一个名为constructor的属性,但它不会做你想的那样,通常最好避免)。

我看到的唯一缺点是你不能继承构造函数,所以每次你创建一个新的子类,你必须编写一个调用基本构造函数的构造函数,即使你的子类的构造函数什么也不做:

代码语言:javascript
复制
function Square() {
    Shape.apply(this, arguments);
}
Square.inherit(Shape);
票数 6
EN

Stack Overflow用户

发布于 2009-10-03 16:18:48

为什么需要这样做?JavaScript没有严格的类层次结构的概念是有原因的:它真的不能做到。您可能会得到一个在大多数情况下都有效的解决方案,但我不确定您是否能涵盖所有边缘情况。此外,由于JavaScript没有任何接口的概念,因此测试显式继承会导致高度耦合,并且似乎违反了SOLID principles

解决这个问题的一种更好(也更惯用)的方法是使用duck typing。只需测试所需方法的存在,然后调用它。做好必要时捕获异常的准备(无论如何你都应该这样做)。

票数 4
EN

Stack Overflow用户

发布于 2009-10-03 16:52:55

把好的设计论点放在一边,专注于你的问题,问题是你在Function的原型上将isInstance()设置为一个方法,这意味着是Function的对象将会有它,而没有的对象(比如你例子中的Object1Object2 )将不会有它。

我建议将其作为一个方法来实现,而不是将其作为一个静态函数来实现:

代码语言:javascript
复制
function isInstance(object, ofClass) {
  // Same logic as you have, except use 
  // object.prototype instead of this.prototype
}

然后,您可以像这样调用它

代码语言:javascript
复制
isInstance(obj2, Object2);
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/1514151

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档