一    Prototype、__proto__与Object、Function关系介绍

        Function、Object:Js自带的函数对象。
        prototype,每一个函数对象都有一个显示的prototype属性,它代表了对象的原型(Function.prototype函数对象是个例外,没有prototype属性)。
        __proto__:每个对象都有一个名为__proto__的内部隐藏属性,指向于它所对应的原型对象(chrome、firefox中名称为__proto__,并且可以被访问到)。原型链正是基于__proto__才得以形成(note:不是基于函数对象的属性prototype)。
 
       关于上面提到的函数对象,我们来看以下例子,来说明:

        var o1 = {};
        var o2 =new Object();
        
        function f1(){}
        var f2 = function(){}
        var f3 = new Function('str','console.log(str)');
    
        f3('aabb');   // aabb
        console.log('typeof Object:'+typeof Object);            //function
        console.log('typeof Function:'+typeof Function);        //function
        console.log('typeof o1:'+typeof o1);   //object
        console.log('typeof o2:'+typeof o2);   //object
        console.log('typeof f1:'+typeof f1);   //function
        console.log('typeof f2:'+typeof f2);   //function
        console.log('typeof f3:'+typeof f3);   //function
  • 通常我们认为o1、o2是对象,即普通对象;f1、f2、f3为函数。
  • 但是其实函数也是对象,是由Function构造的,
  • f3这种写法就跟对象的创建的写法一样。f1、f2最终也都像f3一样是有Function这个函数构造出来的
  • f1、f2、f3为函数对象,Function跟Object本身也是函数对象。

Js中每个对象(null除外)都和另一个对象相关联,通过以下例子跟内存效果图来分析Function、Object、Prototype、__proto__对象间的关系。

    function Animal(){
        
    }
    var  anim = new Animal();
    
    console.log('***********Animal anim proto*****************');
    console.log('typeof Animal.prototype:' +typeof Animal.prototype);  //object 
    console.log('anim.__proto__===Animal.prototype:'+(anim.__proto__===Animal.prototype));  //true
    console.log('Animal.__proto__===Function.prototype:'+(Animal.__proto__===Function.prototype));  //true
    console.log('Animal.prototype.__proto__===Object.prototype:'+(Animal.prototype.__proto__===Object.prototype));  //true
    
    console.log('***********Function proto*****************');
    console.log('typeof Function.prototype:'+typeof Function.prototype);  //function
    console.log('typeof Function.__proto__:'+typeof Function.__proto__);  //function
    console.log('typeof Function.prototype.prototype:'+typeof Function.prototype.prototype); //undefined
    console.log('typeof Function.prototype.__proto__:'+typeof Function.prototype.__proto__);   //object
    console.log('Function.prototype===Function.__proto__:'+(Function.prototype===Function.__proto__)); //true

console.log('***********Object proto*****************');
    console.log('typeof Object.prototype:'+typeof Object.prototype);  //object
    console.log('typeof Object.__proto__:'+typeof Object.__proto__);  //function
    console.log('Object.prototype.prototype:'+Object.prototype.prototype);  //undefied
    console.log('Object.prototype.__proto__===null:'+(Object.prototype.__proto__===null));  //null

console.log('***********Function Object  proto关系*****************');
    console.log('Function.prototype===Object.__proto__:'+(Function.prototype===Object.__proto__));   //true
    console.log('Function.__proto__===Object.__proto__:'+(Function.__proto__===Object.__proto__));   //true
    console.log('Function.prototype.__proto__===Object.prototype:'+(Function.prototype.__proto__===Object.prototype));   //true

/********************* 系统定义的对象Array、Date ****************************/
    console.log('**************test Array、Date****************');      
    var array = new Array();
    var date = new Date();
    console.log('array.__proto__===Array.prototype:'+(array.__proto__===Array.prototype));   //true
    console.log('Array.__proto__===Function.prototype:'+(Array.__proto__===Function.prototype));  //true
    console.log('date.__proto__===Date.prototype:'+(date.__proto__===Date.prototype));    //true
    console.log('Date.__proto__===Function.prototype:'+(Date.__proto__===Function.prototype));     //true

Function、Object、Prototype、__proto__内存关系图

上面的内存图跟堆栈结构可以参照文章Javascript_01_理解内存分配
        堆区图说明:
 
        Function.prototype函数对象图内部表示prototype属性的红色虚框,只是为了说明这个属性不存在。

        通过上图Function、Object、Prototype关系图中,可以得出一下几点:
  1. 所有对象所有对象,包括函数对象的原型链最终都指向了Object.prototype,而Object.prototype.__proto__===null,原型链至此结束。
  2. Animal.prototype是一个普通对象。
  3. Object是一个函数对象,也是Function构造的,Object.prototype是一个普通对象。
  4. Object.prototype.__type__指向null。
  5. Function.prototype是一个函数对象,前面说函数对象都有一个显示的prototype属性,但是Function.prototype却没有prototype属性,即Function.prototype.prototype===undefined,所有Function.prototype函数对象是一个特例,没有prototype属性。
  6. Object虽是Function构造的一个函数对象,但是Object.prototype没有指向Function.prototype,即Object.prototype!==Function.prototype。


二    Prototype跟Constructor关系
介绍

         在 JavaScript 中,每个函数对象都有名为“prototype”的属性(上面提到过Function.prototype函数对象是个例外,没有prototype属性),用于引用原型对象。此原型对象又有名为“constructor”的属性,它反过来引用函数本身。这是一种循环引用(i.e. Animal.prototype.constructor===Animal)。
 
        通过以下例子跟内存效果图来分析Prototype、constructor间的关系。
    console.log('**************constructor****************');

console.log('anim.constructor===Animal:'+(anim.constructor===Animal))    ;    //true
    console.log('Animal===Animal.prototype.constructor:'+(Animal===Animal.prototype.constructor))    ;    //true
    console.log('Animal.constructor===Function.prototype.constructor:'+(Animal.constructor===Function.prototype.constructor));   //true
    console.log('Function.prototype.constructor===Function:'+(Function.prototype.constructor===Function));    //true
    console.log('Function.constructor===Function.prototype.constructor:'+(Function.constructor===Function.prototype.constructor));    //true

console.log('Object.prototype.constructor===Object:'+(Object.prototype.constructor===Object));    //true
    console.log('Object.constructor====Function:'+(Object.constructor===Function));    //true

 prototype、constructor内存关系图(在Function、Object、Prototype关系图上加入constructor元素):

        上图中,红色箭头表示函数对象的原型的constructor所指向的对象。
  1. 注意Object.constructor===Function;本身Object就是Function函数构造出来的
  2. 如何查找一个对象的constructor,就是在该对象的原型链上寻找碰到的第一个constructor属性所指向的对象。
 
参考:
http://www.libuchao.com/2012/05/14/prototypes-in-javascript/ (JavaScript 的原型对象 Prototype)
http://rockyuse.iteye.com/blog/1426510 (理解js中的原型链,prototype与__proto__的关系)
 
from:http://www.blogjava.net/heavensay/archive/2013/10/20/405440.html

【转】Js中Prototype、__proto__、Constructor、Object、Function关系介绍的更多相关文章

  1. js中prototype和constructor的认识

    最初对js中 object.constructor 的认识: 我们都知道,在JS中有一个function的东西.一般人们叫它函数.比如下面的代码 function Person(name)    {  ...

  2. js中prototype,constructor的理解

    连看4篇前辈的文章,记录一些知识点 Javascript继承机制的设计思想 Javascript 面向对象编程(一):封装 Javascript面向对象编程(二):构造函数的继承 Javascript ...

  3. Javascript Prototype __proto__ constructor 三者的关系

    JavaScript三大毒瘤 --- this,原型链,作用域 在我等菜鸟一步一步升级中的过程中,这三个概念总是困扰这我们(可能只有我吧,我比较蠢).这三个东西往往都很绕,今天我就来分享一下我对原型. ...

  4. Js中Prototype、__proto__、Constructor、Object、Function关系介绍

    一. Prototype.__proto__与Object.Function关系介绍 Function.Object:都是Js自带的函数对象.prototype,每一个函数对象都有一个显式的proto ...

  5. 再次理解JS的prototype,__proto__和constructor

    个人总结: 下面这篇文章很好的讲解了js原型,原型链,个人的总结是要记住这三个属性 prototype.__proto__和constructor 首先明确,js中一切都是对象object(A). ( ...

  6. vue.js 中 data, prop, computed, method,watch 介绍

    vue.js 中 data, prop, computed, method,watch 介绍 data, prop, computed, method 的区别 类型 加载顺序 加载时间 写法 作用 备 ...

  7. js in depth: Object & Function & prototype & __proto__ & constructor & classes inherit

    js in depth: Object & Function & prototype & proto & constructor & classes inher ...

  8. js中prototype,__proto__,constructor之间的关系

    首先,我们需要了解三点: 1. 只要创建一个任意新函数,就会根据一个prototype属性,该属性指向函数的原型对象: 2. 每一个原型对象都会自动获得一个constructor属性,该属性只想pro ...

  9. javascript中prototype、constructor以及__proto__之间的三角关系

    三者暧昧关系简单整理 在javascript中,prototype.constructor以及__proto__之间有着“著名”的剪不断理还乱的三角关系,楼主就着自己对它们的浅显认识,来粗略地理理以备 ...

随机推荐

  1. Linux——【rpm、yun、源码包】安装

    RPM包或者安装源码包 在windows下安装一个软件很轻松,只要双击.exe的文件,安装提示连续“下一步”即可,然而linux系统下安装一个软件似乎并不那么轻松,因为我们不是在图形界面下.所以我们要 ...

  2. jquery返回顶部和底部插件和解决ie6下fixed插件

    (function($){ //返回顶部和底部插件 $.fn.extend({ goTopBootom:function (options){ //默认参数 var defaults = { &quo ...

  3. Redis启动和关闭

    带配置文件启动 ./redis-server redis.conf 关闭 无密码模式  ./redis-cli -h xxx -p xxx shutdown 密码模式  ./redis-cli -h ...

  4. Python 递归返回树形菜单JSON串 <flask>

    需求:菜单管理功能(增.删.改),多级树形菜单展示 数据库表设计 create table if not exists Menu( id serial primary key , title ) no ...

  5. oracle 报错:ORA-02019 未找到数据库的连接说明

    一.问题描述 我之前连的是别的数据库,现在更换了数据库的连接,然后就报了如下的错误: 我使用的是NHibernate,我找到映射文件后发现我用了dblink,代码中table="COM_OR ...

  6. c#-FrameWork01

    Framwork ArrayList l  集合类似于数组,同样是用来存放连续数据的,但集合的功能比数组更强大 l  集合和数组的最大区别:数组一旦定义以后就无法改变其大小,而集合可以动态的改变其大小 ...

  7. File 类 的基本操作

    //  File 类(静态类)   File 的缺点:只能用来读小文件 (它是一下子全都读进去) //创建一个文件 // File.Create(@"C:\Users\wbrm\Deskto ...

  8. Log4Net 之初体验

    今天试了一下关于日志的一个插件——Log4Net 关于这个插件就不过多描述了,有很多人用,也挺好用比较方便,所以在此记录下使用过程. 一.建一个mvc 空网站 名字叫 Log4NetTest 二.下载 ...

  9. 插入排序——Java实现

    一.排序思想 从数组第一个元素开始(0下标),该元素可以认为已经被排序: 取出待排序列中第一个元素,然后从“有序”序列中,从后往前扫描: 如果该元素(有序序列)大于待插入元素(待排序列),将该元素后移 ...

  10. OLEDB 简单数据查找定位和错误处理

    在数据库查询中,我们主要使用的SQL语句,但是之前也说过,SQL语句需要经历解释执行的步骤,这样就会拖慢程序的运行速度,针对一些具体的简单查询,比如根据用户ID从用户表中查询用户具体信息,像这样的简单 ...