javascript 检查对象是否是类的“直接示例”

332nm8kg  于 2023-04-19  发布在  Java
关注(0)|答案(7)|浏览(155)

我有两个班:

class Bar extends Foo { // Foo isn't relevant
  constructor(value) {
    if (!(value instanceof Foo)) throw "InvalidArgumentException: (...)";
    super();
    this.value = value;
  }
}

class Baz extends Bar {
  constructor(value) {
    super(value);
  }
}

Barconstructor检查value是否是Foo的示例,如果不是,则抛出错误。至少,这是我希望它做的。如果您传递BarBaz作为值,则if语句也返回true。目标是只让Foo s通过。
我已经找到了this answer,但这并没有真正回答我的问题。

ndh0cuux

ndh0cuux1#

检查构造函数:

if (!value || value.constructor !== Foo)
  throw 'InvalidArgumentException: (...)';

或者对象的原型(这更类似于instanceof所做的):

if (!value || Object.getPrototypeOf(value) !== Foo.prototype)
  throw 'InvalidArgumentException: (...)';
nhhxz33t

nhhxz33t2#

你可以使用Object.getPrototypeOf(yourObj)Foo.prototype之间的比较来查看yourObj是否确实是Foo的示例。你可以通过继续为每个级别调用Object.getPrototypeOf来向上移动链。
示例:

class Foo {}

class Bar extends Foo {}
class Baz extends Bar {}

const foo = new Foo();
const bar = new Bar();
const baz = new Baz();

// For this function:
// - level 0 is self
// - level 1 is parent
// - level 2 is grandparent
// and so on.
function getPrototypeAt(level, obj) {
    let proto = Object.getPrototypeOf(obj);
    while (level--) proto = Object.getPrototypeOf(proto);
    return proto;
}

console.log("bar is a foo:", bar instanceof Foo);
console.log("baz is a foo:", baz instanceof Foo);
console.log("foo is exactly a foo:", getPrototypeAt(0, foo) === Foo.prototype);
console.log("bar is exactly a foo:", getPrototypeAt(0, bar) === Foo.prototype);
console.log("bar is direct child of foo:", getPrototypeAt(1, bar) === Foo.prototype);
console.log("baz is direct child of foo:", getPrototypeAt(1, baz) === Foo.prototype);
console.log("baz is direct child of bar:", getPrototypeAt(1, baz) === Bar.prototype);
console.log("baz is grandchild of foo:", getPrototypeAt(2, baz) === Foo.prototype);
kcwpcxri

kcwpcxri3#

你应该测试value的内部[[Prototype]]是否正好是Foo.prototype。你可以用Object.getPrototypeOf得到内部[[Prototype]]

if ( Object.getPrototypeOf( value ) !== Foo.prototype )
   throw "InvalidArgumentException: (...)";
8yparm6h

8yparm6h4#

如果你知道你所有的类,你可以使用

if(!(value instanceof Foo && !(value instanceof Bar) && !(value instanceof Baz)))
pgccezyw

pgccezyw5#

下面是helper函数:

function isDirectChild(object, constructor) {
    return Object.getPrototypeOf(object) === constructor.prototype;
}

console.log(
    isDirectChild([], Array), // true
    isDirectChild([], Object), // false
);
6uxekuva

6uxekuva6#

我创建了一个函数来检查DOM类和元素之间的关系

const getCreator = instance => Object.getPrototypeOf(instance).constructor.name;
// usage
getCreator(document.documentElement) === "HTMLHtmlElement;
whlutmcx

whlutmcx7#

问题是你引用的所有类都是Foo的后代。比如new Baz() instanceOf Bar && new Bar() instanceOf Foo === true。所以当你问is Bar instanceOf Foo时,它将通过继承为true。
由于在JS中没有Java getClass()等价物,你应该使用如下代码:

if (value.constructor.name !== Foo.name)

相关问题