Класс JavaScript: (экземпляр этого) - PullRequest
0 голосов
/ 08 ноября 2018

Я хочу проверить, является ли объект экземпляром текущего класса он отлично работает вне класса, но выдает ошибку, если я вызвал его из класса

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 ) мы не можем использовать: вернуть obj instanceof этого,

, поскольку (это) является объектом (т. Е. Obj instanceof OBJECT),

чтобы мы могли использовать объект constractor:

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: (по: @ Томас ) сделать функцию "проверка" статической

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

Ответы [ 3 ]

0 голосов
/ 08 ноября 2018

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.getPrototypeOf для извлечения прототипа из this:

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))
0 голосов
/ 08 ноября 2018

имо. 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}
0 голосов
/ 08 ноября 2018

Конкретное сообщение об ошибке:

Uncaught TypeError: Правая часть 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
...