JavaScript class: (这个例子)

JavaScript class: (instanceof this)

我想检查一个对象是否是当前对象的实例 class 它在 class 外部工作正常,但如果我从 class

内部调用它,则会出错

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:(作者: 我们不能使用:return obj instanceof this,

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

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

return obj instanceof this.constructor

方法#2:(通过:

   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:(作者:) 使函数 "check" 静态

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

具体报错信息为:

Uncaught TypeError: Right-hand side of 'instanceof' is not callable

上线

return (obj instanceof this)

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

尝试引用对象的 构造函数 ,它将指向 class (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

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))

imo。 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}