源码网商城,靠谱的源码在线交易网站 我的订单 购物车 帮助

源码网商城

javascript instanceof 内部机制探析

  • 时间:2020-06-29 23:08 编辑: 来源: 阅读:
  • 扫一扫,手机访问
摘要:javascript instanceof 内部机制探析
比如:
[u]复制代码[/u] 代码如下:
// 代码 1 function Pig() {} var pig = new Pig(); alert(pig instanceof Pig); // => true function FlyPig() {} FlyPig.prototype = new Pig(); var flyPig = new FlyPig(); alert(flyPig instanceof Pig); // => true
来看另一段代码:
[u]复制代码[/u] 代码如下:
// 代码 2 function Pig() { Pig.prototype = {/* some code */} } var pig = new Pig(); alert(pig instanceof Pig); // => false
为何上面的猪 pig 不再是猪 Pig 了呢? 当一个对象是某个类的实例时,意味着这个对象具有该类的方法和属性。在 JavaScript 中,一个猪类的特性体现在原型中:
[u]复制代码[/u] 代码如下:
// 代码 3 function Pig() {} Pig.prototype = { "吃猪食": function() {}, "睡觉": function() {}, "长膘": function() {} }; var pig = new Pig(); alert(pig instanceof Pig); //=> true
如果动态改变了猪的特性,让猪变成了牛:
[u]复制代码[/u] 代码如下:
// 代码 4 Pig.prototype = { "吃草": function() {}, "犁田": function() {} }; var niu= new Pig(); alert(pig instanceof Pig); //=> false alert(niu instanceof Pig); //=> true
当未改变 Pig 的 prototype 时,猪还是猪,因此代码 3 中 pig 是 Pig 的实例。当改变 prototype 后,猪已经不是猪,而是披着猪皮的牛了。因此代码 4 中 pig 不再是 Pig 的实例,niu 反而是 Pig 的实例。 进一步分析前,先回顾一下 new 的内部机制。代码 2 中的 new Pig() 实际上等价为:
[u]复制代码[/u] 代码如下:
// 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. 已经可以大胆推论出:instanceof 判断 pig 是不是 Pig 的依据是:看隐藏的 pig.__proto__ 属性是否等于 Pig.prototype ! 为了进一步确认,我们可以在 Firefox 下模拟 instanceof 的内部实现代码:
[u]复制代码[/u] 代码如下:
/** * Gecko 引擎下,模拟 instanceof */ function _instanceof(obj, cls) { // instanceof 的左操作数必须是非null对象或函数对象 if((typeof obj !== "object" || obj === null) && typeof obj !== "function") { return false; } // instanceof 的右操作数必须是函数对象 if(typeof cls !== "function") { throw new Error("invalid instanceof operand (" + cls + ")"); } // 向上回溯判断 var p = obj.__proto__, cp = cls.prototype; while(p) { if(p === cp) return true; p = p.__proto__; } return false; }
测试页面:simulate-intanceof.html 最后考考大家:
[u]复制代码[/u] 代码如下:
function Bird() {} var bird = new Bird(); var o = {}; bird.__proto__ = o; Bird.prototype = o; alert(bird instanceof Bird); // true or false?
  • 全部评论(0)
联系客服
客服电话:
400-000-3129
微信版

扫一扫进微信版
返回顶部