You're right that JavaScript doesn't have classes (yet), but it does have constructor functions, an instanceof
operator that defines a relationship between objects and constructors, and a form of inheritance based on prototype chains.
obj instanceof ctor
is true when ctor.prototype
is on obj
's prototype chain.
Modulo the caveat below, you could implement instanceof
in EcmaScript 5 thus
function isInstanceOf(obj, ctor) {
var proto = ctor.prototype;
if (typeof obj === "object" || typeof obj === "function") {
while (obj) {
if (obj === proto) { return true; }
obj = Object.getPrototypeOf(obj);
}
}
return false;
}
Unless you go around reassigning prototypes (o = new MyConstructor(); MyConstructor.prototype = somethingElse
) it should be the case that new MyConstructor() instanceof MyConstructor
.
Section 15.3.5.3 explains this in detail.
15.3.5.3 [[HasInstance]] (V)
Assume F is a Function object.
When the [[HasInstance]] internal method of F is called with value V, the following steps are taken:
If V is not an object, return false.
Let O be the result of calling the [[Get]] internal method of F with property name "prototype".
If Type(O) is not Object, throw a TypeError exception.
Repeat
- Let V be the value of the [[Prototype]] internal property of V.
- If V is null, return false.
- If O and V refer to the same object, return true.
This isn't the whole story because host objects (like DOM nodes) are allowed to implement the [[HasInstance]]
internal method however they like but most browsers implement host objects to behave as closely to native objects as possible.
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…