admin管理员组文章数量:1323714
function A(){}
A.prototype = "Foo bar";
new A() instanceof A;
// TypeError: Function has non-object prototype 'Foo bar' in instanceof check
As you can see, if the prototype of a constructor is not an object, it will fail and throw an error. Is there a way to make sure instanceof
will not fail?
typeof new A().constructor.prototype === "object"
and
typeof Object.getPrototypeOf(new A()) === "object"
apparently do not work.
function A(){}
A.prototype = "Foo bar";
new A() instanceof A;
// TypeError: Function has non-object prototype 'Foo bar' in instanceof check
As you can see, if the prototype of a constructor is not an object, it will fail and throw an error. Is there a way to make sure instanceof
will not fail?
typeof new A().constructor.prototype === "object"
and
typeof Object.getPrototypeOf(new A()) === "object"
apparently do not work.
Share Improve this question asked Apr 7, 2017 at 2:24 Derek 朕會功夫Derek 朕會功夫 94.4k45 gold badges197 silver badges253 bronze badges 8-
2
Maybe wrap it in
try/catch
? – Barmar Commented Apr 7, 2017 at 2:25 -
1
How about
typeof A.prototype === "object"
? – Barmar Commented Apr 7, 2017 at 2:27 - @Barmar How did I not think of that before? Thanks. – Derek 朕會功夫 Commented Apr 7, 2017 at 2:30
-
@Barmar Close, but
typeof A.prototype == "object" && A.prototype != null || typeof A.prototype == "function"
it is – Bergi Commented Apr 7, 2017 at 2:31 -
1
why would you ever do
A.prototype = "Foo bar";
in the first place – Jaromanda X Commented Apr 7, 2017 at 2:41
4 Answers
Reset to default 3The error says A.prototype
needs to be an object, so you should check for that:
function isObject(x) {
return x != null && (typeof x == "object" || typeof x == "function");
}
but isObject(A.prototype)
is not all you can do to assert an instanceof
call won't throw. Going by the spec, you should test
function allowsInstanceCheck(C) {
try {
if (!isObject(C)) return false;
var m = C[Symbol.hasInstance];
if (m != null) return typeof m == "function";
if (typeof C != "function") return false;
return isObject(C.prototype);
} catch (e) {
// any of the property accesses threw
return false;
}
}
Use try/catch
to catch the error;
function isItA(obj) {
try {
return obj instanceof A;
} catch (e) {
return false; //
}
}
function A() {}
A.prototype = "Foo bar";
function B() {}
B.prototype = "Baz Quux";
console.log(isItA(new A()));
console.log(isItA(new B()));
Perhaps not really an answer, but an interesting conclusion.
When a function is called as a constructor, if its prototype property isn't an Object, then the new instance is assigned the intrinsicDefaultProto as its [[Prototpye]]
as described in GetPrototypeFromConstructor.
In the process of creating a new instance, the intrinsicDefaultProto is passed the value of the fallbackProto, which seems to be (in Firefox at least), Object.prototype.
And since the constructor property of Object.prototype is Object, then testing whether the instance's constructor property references the candidate object won't work either.
function Foo(){}
Foo.prototype = 'A';
var foo = new Foo();
// foo inherits directly from Object.prototype, not Foo
console.log(Object.getPrototypeOf(foo) == Object.prototype) // true
// foo also inherits constructor property from Object.prototype
console.log(foo.constructor == Object) // true
So a circumstance in which instanceof fails likely points to more serious issues in the program design or implementation. Hiding such errors seems to not be a good idea (unless the intention is to leave traps within the code for future maintainers to discover).
I use: typeof o.prototype === "function" && o instanceof f
本文标签: javascriptCheck if quotinstanceofquot is going to failStack Overflow
版权声明:本文标题:javascript - Check if "instanceof" is going to fail - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1742120968a2421694.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论