zoukankan      html  css  js  c++  java
  • js的__proto__,prototype、constructor属性

    根据JavaScript核心以及原文JavaScript. The core.加上自己的理解做一个总结。

    prototype与__proto__、constructor理解

    • prototype是每个函数都有的属性,它指向的是一个(原型)对象,是创建原型链的重要属性;

    • __proto__描述实例化对象与其原型对象之间的关系,每一个对象均可看成另一个对象的实例对象,故每一个对象都有__proto__属性;

    • constructor是每个原型对象都有的属性,始终指向创建该对象(自身)的构造函数,每一个函数都有prototype属性,prototype.constructor指向该构造函数。

    以内置对象Object()为例:

        var obj=new Object();  
        typeof obj.__proto__;//"object"  
        obj.__proto__===Object.prototype;//true  
        obj.constructor;//function Object(){native code}  
        Object.prototype.constructor===obj.constructor;//true  
    

      obj是构造函数Object()的实例化对象,则必然有__proto__属性指向构造该实例对象的原型即Object.prototype,也是一个对象。

    流程图

      可以从结果知道obj.constructor指向了obj对象的构造函数Object(),然而这并不表明obj自身有constructor属性,而是根据原型链向上查找。当自身没有找到属性,就会查找obj.__proto__,就是Object.prototype,从而找到constructor属性,由Object.prototype.constructor===obj.constructor;返回true就可以知道。

    内置函数与Function.prototype的关系

    js原型链

    这个图表明了整个js中函数与对象的关系,以及prototype、__proto__、constructor的指向。

      由上图可以知道,Object()其实也是一个Function()函数的实例化对象,也有__proto__属性,指向Function.prototype从而形成了原型链。

    W3C中对Math对象有如下注释:

    Math 对象并不像 Date 和 String 那样是对象的类,因此没有构造函数 Math(),像 Math.sin() 这样的函数只是函数,不是某个对象的方法。您无需创建它,通过把 Math 作为对象使用就可以调用其所有属性和方法。

    在控制台运行以下代码,以Object()、Array()、以及Math对象为例:

        Object.__proto__===Function.prototype;//true
        Object.constructor;//function Function(){native code}
        Object.constructor===Object.__proto__.constructor;//true
        Array.__proto__===Function.prototype;//true
        Array.constructor;//function Function(){native code}
        Array.constructor===Array.__proto__.constructor;//true
        Math.__proto__===Object.prototype;//true
        Math.prototype;//undefined
        Math.constructor;//function Object(){native code}
        Math.constructor===Math.__proto__.constructor;//true
    
    • 除了Math对象以外,其他的内置对象均是Function通过new创建出来的,也是函数,既然是函数则肯定有prototype属性,它所指向的是它们自身的原型函数Array.prototype,String.prototype等。

    • 它们的__proto__属性均指向它们构造函数的原型Function.prototype。它们的constructor属性均指向它们的构造函数function Function(){...};

    • Math对象虽然没有prototype属性,但是它也有__proto__属性,指向Object.prototype。

    注意:实例化对象自身是没有constructor属性,是从其__proto__原型中继承过来的。

    Function()函数是通过new自己本身创建出来的,Function.__proto__指向的是Function.prototype,Function.constructor指向的是function Function(){...}。

    Function.prototype与Object.prototype的关系

      由上面可以知道内置对象(除Math)的__proto__属性都指向Function.prototype,那Function.prototype呢?
    在控制台运行以下代码:

        typeof Function.prototype;//function
        Function.prototype.prototype;//undefined
        Function.prototype.__proto__===Object.prototype;//true
        typeof Object.prototype;//"object"
        Object.prototype.__proto__;//null
    

    可以看出Function.prototype其实是一个函数,但是它的prototype指向的值却是undefined,这算是一个特例。Function.prototype的__proto__属性指向Object.prototype。

    所有的对象原型包括函数对象原型最终都指向Object.prototype,而Object.prototype的__proto__指向null

    普通函数和对象的prototype、__proto__、constructor

      自定义构造函数Test(),查看它的prototype、__proto__、constructor:

        function Test(num1,num2){
             this.n1=num1;
             this.n2=num2;
        }
        var obj=new Test();
    

    结果如下:
    结果

    object.prototype形成了原型链;Test.__proto__指向构造函数Function()的原型Function.prototype,而Function.prototype.__proto__指向Object.prototype也形成了原型链;Test.prototype的constructor属性指向了构造该对象原型的构造函数function Test()。

    总结:

    • 每一个函数都有prototype属性,可以指向一个对象或者null;

    • __proto__描述实例化对象与其原型对象之间的关系,每一个对象均可看成另一个对象的实例对象,故每一个对象都有__proto__属性;

    • 每一个function.prototype对象默认有一个属性constructor,且constructor始终指向创建该对象原型的构造函数;

    • 所有内置对象中,除了Math对象没有构造函数以外,其余所有内置对象均为Function()函数通过new创建出来的实例化对象,Function()函数是通过new自己本身创建出来的,Function.__proto__指向的是Function.prototype,Function.constructor指向的是function Function(){...}。

    • Function.prototype是一个函数,但它是个特例,没有prototype属性。


    参考

    1:http://weizhifeng.net/javascript-the-core.html
    2:http://dmitrysoshnikov.com/ecmascript/javascript-the-core/

  • 相关阅读:
    h5-7
    h5-6
    h5-5
    h5-4
    h5-3
    h5-2
    return
    字符串的常用操作
    字符串中的转义字符
    字典的统计,合并,清空操作
  • 原文地址:https://www.cnblogs.com/aicanxxx/p/6844150.html
Copyright © 2011-2022 走看看