【问题标题】:JavaScript class: (instanceof this)JavaScript 类:(this 的实例)
【发布时间】:2018-11-08 08:32:15
【问题描述】:

我想检查一个对象是否是当前类的实例 它在课堂外工作正常,但如果我从课堂内调用它会出错

class test {

  check(obj) {
    return (obj instanceof this) //error: this is not a function

  }
}


const obj = new test()

console.log(obj instanceof test) //true
console.log(new test().check(obj)) //ERROR

解决:

方法#1:(作者:@CertainPerformance 我们不能使用:return obj instanceof this,

因为(this)是一个对象(即:obj instanceof OBJECT),

所以我们可以使用构造器对象:

return obj instanceof this.constructor

方法#2:(作者:@Matías Fidemraizer

   return Object.getPrototypeOf(this).isPrototypeOf () //using this->better 

   //or: className.prototype.isPrototypeOf (obj) 
      //if you know the class name and there is no intent to change it later

方法#3:(作者:@Thomas) 使函数“检查”静态

static check(obj) {
    // now `this` points to the right object, the class/object on which it is called,        
    return obj instanceof this;
  }

【问题讨论】:

    标签: javascript class object this instanceof


    【解决方案1】:

    具体报错信息为:

    未捕获的类型错误:'instanceof' 的右侧不可调用

    上线

    return (obj instanceof this)
    

    这是有道理的——instanceof 的右侧应该是一个(或函数),例如test。不能调用不是函数的东西(比如对象),所以<something> instanceof <someobject> 没有意义。

    尝试引用对象的 构造函数,它将指向类 (test):

    return obj instanceof this.constructor
    

    class test{
      check(obj){
        return obj instanceof this.constructor
    
      }
    }
    obj=new test()
    console.log(obj instanceof test) //true
    console.log(new test().check(obj)) //ERROR

    【讨论】:

      【解决方案2】:

      instanceof 旨在测试某个给定原型的给定实例是否提供构造函数。

      实际上,您无法检查{} instanceof {},这才是您真正在做的事情。

      这就是第一个检查有效,另一个无效的原因。

      使用Object#isPrototypeOf怎么样?

      class A {
         check (x) {
             return A.prototype.isPrototypeOf (x) 
         }
      }
      
      class B extends A {}
      
      class C {}
      
      const a = new A ()
      const b = new B ()
      const c = new C ()
      
      console.log (a.check (a))
      console.log (a.check (b))
      console.log (a.check (c))

      或者,正如@vlaz 在某些评论中指出的那样,您可以使用Object.getPrototypeOfthis 中提取原型:

      class A {
         check (x) {
             return Object.getPrototypeOf(this).isPrototypeOf (x) 
         }
      }
      
      class B extends A {}
      
      class C {}
      
      const a = new A ()
      const b = new B ()
      const c = new C ()
      
      console.log (a.check (a))
      console.log (a.check (b))
      console.log (a.check (c))

      【讨论】:

      • 谢谢@Matías,但我如何检查对象是否是当前类的实例?还有别的想法吗?
      • @xxyy 重新检查我重新更新的答案。看看Object#isPrototypeOf 如何让您能够测试继承的类是否也是A
      • 如果您不想通过名称 (A.prototype) 引用当前类,也可以使用 Object.getPrototypeOf(this)
      • 它有效,但是当我将“A.prototype”更改为“this.prototype”时,它给了我一个错误,我需要使用它
      • @vlaz 你是对的,我可以在我的回答中证明这一点,谢谢
      【解决方案3】:

      我。 check 不属于现在的位置。将此功能编写为实例方法是没有意义的;最好是静态方法:

      class Test {
        // check is now a static method
        static check(obj) {
          // and now `this` points to the right object, the class/object on wich it is called, 
          // not some instance.
          return obj instanceof this;
        }
      }
      
      // extending the class Test
      class Test2 extends Test {}
      
      const obj = new Test(), obj2 = new Test2();
      // Tests
      [
        () => obj instanceof Test, //true
        () => Test.check(obj), //true
        () => new Test().check(obj), //ERROR: because `check` is no longer an instance method
      
        // Test2 has inherited static check:
        () => obj2 instanceof Test2, //true
        () => Test2.check(obj2), //true
        () => Test2.check(obj), //false, obj is no instance of Test2
        () => Test.check(obj2), //true
        () => {
          var check = Test.check;
          // ERROR, because here you call `check` with no class/object
          return check(obj);  
        }
      ].forEach(fn => {
        try {
          console.log("%s: %o", fn, fn());
        } catch (err) {
          console.error(err);
        }
      });
      .as-console-wrapper{top:0;max-height:100%!important}

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2010-12-17
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2019-02-21
        • 2017-02-06
        相关资源
        最近更新 更多