instanceof运算符在后续更改为继承链时返回false

Ste*_*hen 5 javascript prototype

在构造函数上设置原型时,instanceof操作符仅返回true原型更改.为什么?

function SomeConstructorFunction() {
}

function extendAndInstantiate(constructorFn) {
    constructorFn.prototype = {}; //Can be any prototype
    return new constructorFn();
}

var child1 = extendAndInstantiate(SomeConstructorFunction);
console.log(child1 instanceof SomeConstructorFunction); //true

var child2 = extendAndInstantiate(SomeConstructorFunction);
console.log(child1 instanceof SomeConstructorFunction); //false
console.log(child2 instanceof SomeConstructorFunction); //true
Run Code Online (Sandbox Code Playgroud)

Aad*_*hah 4

原型继承可能有点令人费解。我已经在下面的答案中写了一个关于原型继承的简单解释,我建议您阅读它:https ://stackoverflow.com/a/8096017/783743

现在回答你的问题。考虑以下函数:

function F() {}
Run Code Online (Sandbox Code Playgroud)

F我可以创建一个using实例,new如下所示:

var f = new F;
Run Code Online (Sandbox Code Playgroud)

正如预期的f instanceof F回报true。这是因为instanceof操作符会F.prototype在原型链中进行检查,如果存在则f返回。true请参阅我上面链接的答案。

现在假设我创建一个新函数,G如下所示并设置F.prototypeG.prototype

function G() {}

F.prototype = G.prototype;
Run Code Online (Sandbox Code Playgroud)

如果我现在f instanceof F再次评估false则返回。这是因为F.prototype不再位于原型链中f(记住F.prototype是现在G.prototype)。

现在让我们创建一个新实例F

var g = new F;
Run Code Online (Sandbox Code Playgroud)

如果你评估g instanceof G它会返回true即使g = new F. 这是因为G.prototype存在于 的原型链中g

这不是一个错误。这就是 JavaScript 的工作方式。事实上,我们可以利用此功能来创建一些非常有趣的函数:使用自定义原型实例化 JavaScript 函数