大家都说JavaScript的属性多,记不过来,各种结构复杂不易了解。确实JS是一门入门快提高难的语言,但是也有其他办法可以辅助记忆。下面就来讨论一下JS的一大难点-对象布局,究竟设计JS这门语言的人当时是怎么做的?设计完之后又变成了什么?

我们来看一张图:

 相信大家对这张图都不陌生了,构造函数有一个prototype属性指向其原型。相反原型也有一个constructor指向构造函数。与此同时实例也有一个constructor指向构造函数,这简直就是互相捆绑生怕找不到啊不是吗?

还有一个我们称之为秘密链接的__proto__属性,原谅我第一眼见到这个属性就觉得特别的怪,_下划线都用上了,驼峰命名规则呢?好吧,这是部分浏览器暴露出来的一个指针而已,可能当时设计的时候随便写出来,突然发现这货有点用就留下了(纯属个人猜测)。

附上上图的检测代码不信的童鞋可以自己玩玩:

  1. <!DOCTYPE html>
  2. <html>
  3. <head>
  4. <meta charset="utf-8">
  5. <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
  6. <title>JS函数原型,函数,实例的关系证明</title>
  7. </head>
  8. <body>
  9. <script type="text/javascript">
  10. function Foo(){} //构造函数
  11. var a = new Foo(); //实例
  12. console.log(Foo===Foo.prototype.constructor); //true
  13. console.log(a.constructor===Foo); //true
  14. console.log(Foo.prototype===Foo.prototype); //true
  15. console.log(a.__proto__===Foo.prototype); //true
  16. </script>
  17. </body>
  18. </html>

上面只是基础而已,下面才是真正的重点,为了修改这张图我可是煞费苦心,绞尽脑汁,不知道死了多少脑细胞。

可能大家已经看晕了,没事冲杯咖啡慢慢看。下面是相应的证明代码,友情提示sublimeText看更爽:

  1. <!DOCTYPE html>
  2. <html>
  3. <head>
  4. <meta charset="utf-8">
  5. <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
  6. <title>JavaScript对象布局</title>
  7. </head>
  8. <body>
  9. <script type="text/javascript">
  10. //以下代码全部为true
  11. console.log("1:"+(Object.prototype.__proto__ === null));
  12. console.log("2:"+(Function.prototype.__proto__===Object.prototype));
  13. console.log("3.1:"+(Number.__proto__ === Function.prototype));
  14. console.log("3.2:"+(Boolean.__proto__ === Function.prototype));
  15. console.log("3.3:"+(String.__proto__ === Function.prototype));
  16. console.log("3.4:"+(Object.__proto__ === Function.prototype));
  17. console.log("3.5:"+(Function.__proto__ === Function.prototype));
  18. console.log("3.6:"+(Date.__proto__ === Function.prototype));
  19. console.log("3.7:"+(Error.__proto__ === Function.prototype));
  20. console.log("3.8:"+(Array.__proto__ === Function.prototype));
  21. console.log("3.9:"+(RegExp.__proto__ === Function.prototype));
  22. console.log("4.1:"+(Math.__proto__===Object.prototype));
  23. console.log("4.2"+(JSON.__proto__===Object.prototype));
  24. function Foo(){} //构造函数
  25. var f1 = new Foo(); //实例
  26. console.log("5:"+(Foo===Foo.prototype.constructor));
  27. console.log("6.1:"+(f1.__proto__===Foo.prototype));
  28. console.log("7:"+(f1.constructor===Foo));
  29. console.log("8.1:"+(Number.prototype.__proto__===Object.prototype));
  30. console.log("8.2:"+(Boolean.prototype.__proto__===Object.prototype));
  31. console.log("8.3:"+(String.prototype.__proto__===Object.prototype));
  32. console.log("8.5:"+(Function.prototype.__proto__===Object.prototype));
  33. console.log("8.6:"+(Date.prototype.__proto__===Object.prototype));
  34. console.log("8.7:"+(Error.prototype.__proto__===Object.prototype));
  35. console.log("8.8:"+(Array.prototype.__proto__===Object.prototype));
  36. console.log("8.9:"+(RegExp.prototype.__proto__===Object.prototype));
  37. console.log("9:"+(Foo.__proto__===Function.prototype));
  38. var manfred = new Object();//实例对象
  39. console.log("10:"+(manfred.__proto__===Object.prototype));
  40. console.log("11:"+(Foo.prototype.__proto__===Object.prototype));
  41. //manfred为object构造函数产生,manfred.constructor指向function Object()构造函数
  42. console.log("12:"+(manfred.constructor.__proto__===Function.prototype));
  43. console.log("13:"+(manfred.constructor===Object.prototype.constructor));
  44. var hu = new Function();
  45. console.log("14:"+(hu.constructor.__proto__===Function.prototype));
  46. console.log("15:"+(hu.constructor===Function.prototype.constructor));
  47. </script>
  48. </body>
  49. </html>

相信看完这些代码和原图比较之后大家对JS对象之间的关系已经了如指掌了,确实一开始我也让这货搞得头晕晕的,但是画出这张图之后已经觉得没什么了。大家可以自己动手画一下。

原文地址:请点击这里

总结(补充):

  1. 普通函数的原型是由Object()构造器构造的,同Object.prototype一样是Object()构造器的一个实例
  2. 普通函数是Function()构造器构造的,同Function.prototype一样是Function()构造器的一个实例
  3. 内部原型链_proto_属性是为了实现继承而存在的,这样,我们可以处于任何目的来修改constructor属性,而不用担心实例与父类的一致性。

15条规则解析JavaScript对象布局(__proto__、prototype、constructor)的更多相关文章

  1. javascript--15条规则解析JavaScript对象布局(__proto__、prototype、constructor)

    大家都说JavaScript的属性多,记不过来,各种结构复杂不易了解.确实JS是一门入门快提高难的语言,但是也有其他办法可以辅助记忆.下面就来讨论一下JS的一大难点-对象布局,究竟设计JS这门语言的人 ...

  2. 彻底搞懂js __proto__ prototype constructor

    在开始之前,必须要知道的是:对象具有__proto__.constructor(函数也是对象固也具有以上)属性,而函数独有prototype 在博客园看到一张图分析到位很彻底,这里共享: 刚开始看这图 ...

  3. 8条规则图解JavaScript原型链继承原理

    原形链是JS难点之一,而且很多书都喜欢用一大堆的文字解释给你听什么什么是原型链,就算有图配上讲解,有的图也是点到为止,很难让人不产生疑惑. 我们先来看一段程序,友情提示sublimeText看更爽: ...

  4. JavaScript对象原型写法区别

        体现对象原型分步式写法 //原型分步式写法 //构造函数 function Person(){} //对象原型 Person.prototype.name = 'Avensatr'; Pers ...

  5. JavaScript对象原型写法详解

        体现对象原型分步式写法 //原型分步式写法 //构造函数 function Person(){} //对象原型 Person.prototype.name = 'Avensatr'; Pers ...

  6. JavaScript对象创建,继承

    创建对象 在JS中创建对象有很多方式,第一种: var obj = new Object(); 第二种方式: var obj1 = {};//对象直面量 第三种方式:工厂模式 function Per ...

  7. 面向面试编程——javascript对象的几种创建方式

    javascript对象的几种创建方式 总共有以下几个模式: 1.工厂模式 2.构造函数模式 3.原型模式 4.混合构造函数和原型模式 5.动态原型模式 6.寄生构造函数模式 7.稳妥构造函数模式 1 ...

  8. JavaScript大杂烩4 - 理解JavaScript对象的继承机制

    JavaScript是单根的完全面向对象的语言 JavaScript是单根的面向对象语言,它只有单一的根Object,所有的其他对象都是直接或者间接的从Object对象继承.而在JavaScript的 ...

  9. javascript如何解析json对javascript如何解析json对象并动态赋值到select列表象并动态赋值到select列表

    原文 javascript如何解析json对象并动态赋值到select列表 JSON(JavaScriptObject Notation)一种简单的数据格式,比xml更轻巧.JSON是JavaScri ...

随机推荐

  1. NFC framework

    NFC framework introduce 1 NFC简介 对于NFC,是google在android4.0上推出来的,简单介绍下.近场通讯(NFC)是一系列短距离无线技术,一般需要4cm或者更短 ...

  2. [转]基于AngularJS的前端架构(上)

    模块化 怎么分模块 AngularJS自己有模块的概念,但只是为controller.direcitive.service等提供一个集合的概念,并没有文件调度的功能. 官方推荐的模块分类方法是: an ...

  3. 如何安装altium designer 10

    http://jingyan.baidu.com/article/4dc4084881e2bdc8d946f1f3.html

  4. 38.基于FPGA的FIR设计二

    利用fdatool工具生成的滤波器系数与用代码生成的系数不一致,在网上查询得知,fdatool生成的滤波器系数是有符号小数,而且是浮点型,而代码生成的滤波器系数是定点型有符号数,故不一样. 浮点型数据 ...

  5. c++ 中static关键字

    static可以用于修饰普通的变量和函数,也可以用于修饰类的成员 普通应用 1.修饰普通变量 修饰全局变量:将变量的作用域限制在所属文件 修饰局部变量:将变量的生存周期延迟到程序结束 2.修饰普通函数 ...

  6. openfire插件开发之完美开发

    http://redhacker.iteye.com/blog/1919329 一.说在前面 在继上篇Openfire3.8.2在eclipse中Debug方式启动最简单的方式后,我研究了openfi ...

  7. Introduction to Financial Management

    Recently,i am learning some useful things about financial management by reading <Essentials of Co ...

  8. 如何ping通两台计算机

    如何ping通两台计算机 因为ping是基于IP协议的,所以,先要保证两台计算机在同一个子网中,这里涉及到vlan和子网的概念 若两台主机不在同一个子网中则无法ping通 若两台主机在同一个子网中却p ...

  9. Ombrophobic Bovines - POJ 2391

    Description FJ's cows really hate getting wet so much that the mere thought of getting caught in the ...

  10. zoj 2314 Reactor Cooling 网络流

    题目链接:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=1314 The terrorist group leaded by a ...