JavaScript中的instanceof原理详解

JavaScript中instanceof为一个关键字

用法为:

obj instanceof con

其返回值为true或false。 

对于其原理的阐述一般为“Javascript 的 instanceof 操作符可以用来比较两个操作数的构造函数 constructor”。

但constructor是什么,instanceof的判断依据又到底是什么呢? 

首先看看实现的解释代码:

function _instanceof( obj , func ) {
    while(true) {
       obj = obj.__proto__; // [[prototype]] (hidden) property
       if( obj == null) return false;
       if( obj ==  func.prototype ) return true;
    }
}

简单来说,就是

obj.__proto__[.__proto__] === con.prototype

因此,对instanceof 的原理应理解为

判断obj原型链中是否有con.prototype,用处则为判断obj是否为con的一个实例。

前述的constructor是指obj的构造函数,即obj.__proto,而非obj.__proto__.prototype.constructor的引用。

 

写个样例用来区分,看着样例会容易理解很多。

例子一:

function O2(aa,bb){
    var aa = aa;
    this.bb = bb;
}
//1、正常情况
var o2 = new O2("a2","b2");
console.log(o2 instanceof O2);//true

//2、修改了构造函数的原型对象
var o4 = new O2("a4","b4");
O2.prototype = {};
console.log(o4 instanceof O2);//false

//3、修改了构造函数原型对象的constructor属性
var o6 = new O2("a6","b6");
O2.prototype.constructor = Object;
console.log(o6 instanceof O2);//true

通过上面的例子可以看出,修改O2.prototype.constructor不会影响instanceof的效果。

例子二:

    function O2(aa,bb){
        var aa = aa;
        this.bb = bb;
    }
    function O6(aa,bb){
        var aa = aa;
        this.bb = bb;
    }
    //1、正常情况
    var o2 = new O2("a2","b2");
    console.log(o2 instanceof O2);//true
    console.log(o2.__proto__ === O2.prototype);//true

    // 2、修改了构造函数的原型对象
    var o4 = new O6("a4","b4");    
    console.log(o4 instanceof O6);//true
    function F(){};
    O6.prototype = new F;
    console.log(o4 instanceof O6);//false
    console.log(o4 instanceof F);//false
    console.log(o4.__proto__ === F.prototype);//false

    //3、修改了构造函数原型对象的constructor属性
    var o6 = new O6("a6","b6");
    console.log(o6 instanceof O6);//true
    console.log(o6 instanceof F);//true
    console.log(o6.__proto__.__proto__ === F.prototype);//true    
    console.log(o6.__proto__ === F.prototype);//false

使用这个例子便可以理解instanceof的判断条件:

obj.__proto__[.__proto__] === con.prototype

 

扩展阅读:

例子问答: http://segmentfault.com/q/1010000002697768

内核代码解析1:http://stackoverflow.com/questions/17701102/javascript-prototype-constructor-and-instanceof

内核代码解析2: http://stackoverflow.com/questions/5925063/how-exactly-does-the-instanceof-works-and-relatively-is-it-slow/12874372#12874372

官方详解: https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Operators/instanceof

posted @ 2015-04-22 16:22  WFE-Hank  阅读(969)  评论(0编辑  收藏  举报