进一步分析前,先回顾一下 new 的内部机制。代码 2 中的 new Pig() 实际上等价为: 复制代码 代码如下: // var pig = new Pig() 的等价伪代码: var pig = (function() { var o = {}; o.__proto__ = Pig.prototype; // line 2 Pig.call(o); Pig.prototype = {/* some code */}; // line 4 return o; // line 5 })();
可以看出,在 line 2 时,o.__proto__ 指向了 Pig.prototype 指向的值。但在 line 4 时,Pig.prototype 指向了新值。也就是说,在 line 5 返回时,pig.__proto__ !== Pig.prototype. 正是这个变化,导致了代码 2 中的 pig 不是 Pig.
// 向上回溯判断 var p = obj.__proto__, cp = cls.prototype; while(p) { if(p === cp) return true; p = p.__proto__; } return false; }
测试页面:simulate-intanceof.html
最后考考大家: 复制代码 代码如下: function Bird() {} var bird = new Bird(); var o = {}; bird.__proto__ = o; Bird.prototype = o; alert(bird instanceof Bird); // true or false?