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

我们来看一张图:

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

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

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

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
<title>JS函数原型,函数,实例的关系证明</title>
</head>
<body>
    <script type="text/javascript">
    function Foo(){} //构造函数
    var a = new Foo(); //实例
    console.log(Foo===Foo.prototype.constructor); //true
    console.log(a.constructor===Foo); //true
    console.log(Foo.prototype===Foo.prototype); //true
    console.log(a.__proto__===Foo.prototype); //true
</script>
</body>
</html>

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

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

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
<title>JavaScript对象布局</title>
</head>
<body>
    <script type="text/javascript">
        //以下代码全部为true
        console.log("1:"+(Object.prototype.__proto__ === null));
        console.log("2:"+(Function.prototype.__proto__===Object.prototype));
        console.log("3.1:"+(Number.__proto__ === Function.prototype));
        console.log("3.2:"+(Boolean.__proto__ === Function.prototype));
        console.log("3.3:"+(String.__proto__ === Function.prototype));
        console.log("3.4:"+(Object.__proto__ === Function.prototype));
        console.log("3.5:"+(Function.__proto__ === Function.prototype));
        console.log("3.6:"+(Date.__proto__ === Function.prototype));
        console.log("3.7:"+(Error.__proto__ === Function.prototype));
        console.log("3.8:"+(Array.__proto__ === Function.prototype));
        console.log("3.9:"+(RegExp.__proto__ === Function.prototype));
        console.log("4.1:"+(Math.__proto__===Object.prototype));
        console.log("4.2"+(JSON.__proto__===Object.prototype));
        function Foo(){} //构造函数
        var f1 = new Foo(); //实例
        console.log("5:"+(Foo===Foo.prototype.constructor));
        console.log("6.1:"+(f1.__proto__===Foo.prototype));
        console.log("7:"+(f1.constructor===Foo));
        console.log("8.1:"+(Number.prototype.__proto__===Object.prototype));
        console.log("8.2:"+(Boolean.prototype.__proto__===Object.prototype));
        console.log("8.3:"+(String.prototype.__proto__===Object.prototype));
        console.log("8.5:"+(Function.prototype.__proto__===Object.prototype));
        console.log("8.6:"+(Date.prototype.__proto__===Object.prototype));
        console.log("8.7:"+(Error.prototype.__proto__===Object.prototype));
        console.log("8.8:"+(Array.prototype.__proto__===Object.prototype));
        console.log("8.9:"+(RegExp.prototype.__proto__===Object.prototype));
        console.log("9:"+(Foo.__proto__===Function.prototype));
        var manfred = new Object();//实例对象
        console.log("10:"+(manfred.__proto__===Object.prototype));
        console.log("11:"+(Foo.prototype.__proto__===Object.prototype));
        //manfred为object构造函数产生,manfred.constructor指向function Object()构造函数
        console.log("12:"+(manfred.constructor.__proto__===Function.prototype));
        console.log("13:"+(manfred.constructor===Object.prototype.constructor));
        var hu = new Function();
        console.log("14:"+(hu.constructor.__proto__===Function.prototype));
        console.log("15:"+(hu.constructor===Function.prototype.constructor));
    </script>
</body>
</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. JavaScript对象创建,继承

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

  3. JavaScript对象原型写法区别

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

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

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

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

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

  6. javascript对象转化为基本数据类型规则

    原文:Object-to-Primitive Conversions in JavaScript 对象转化为基础数据类型,其实最终都是用调用对象自带的valueOf和toString两个方法之一并获得 ...

  7. web前端-雅虎34条规则优化

    1.尽量减少HTTP请求次数      终端用户响应的时间中,有80%用于下载各项内容.这部分时间包括下载页面中的图像.样式表.脚本.Flash等.通过减少页面中的元素可以减少HTTP请求的次数.这是 ...

  8. 《C++编程规范:101条规则、准则与最佳实践》学习笔记

    转载:http://dsqiu.iteye.com/blog/1688217 组织和策略问题 0. 不要为小事斤斤计较.(或者说是:知道什么东西不需要标准化) 无需在多个项目或者整个公司范围内强制实施 ...

  9. 第六章:Javascript对象

    对象是javascript的基本数据类型.对象是一种复合值.它将很多值(原始值 或者其他对象)聚合在一起.可通过名字访问这些值.对象也可以看做是属性的无序集合,每个属性都有一个名/值.属性名是字符串, ...

随机推荐

  1. Raspberry Pi 3 --- GPIO control

    Before input 'gpio readall', need install wiringPi download "wiringPi":git clone git://git ...

  2. C++术语俗解

    C++作为一种复杂的编程语言,其最晦涩的莫过于各个术语. 以下就经常使用的术语,逐个俗解(特别声明:为了对术语的更好理解与记忆,仅代表个人的俗识,若有不妥之处望给予指正),分享共勉. 内存:一片计算机 ...

  3. HDU 5398 (动态树)

    Problem GCD Tree 题目大意 n个点的无向完全图,标号1~n,每条边u-->v 的权值为gcd(u,v),求其最大生成树,输出最大边权和. n<=10^5,有多个询问. 解题 ...

  4. KBMMW 4.93.10 win64 一个BUG 修正

    经常有人提到kbmmw 4.93.10 的64 位版本没有32位版本稳定. 经过官方确认,是delphi 编译器生成64 位代码内存偏移地址的错误. 在kbmMWGlobal.pas 中 有一个函数k ...

  5. 实现List按与一个字符串的相似度和字母顺序排序(适用于模糊查询后的排序)

    因公司业务需要,自己写了一个,保存起来以后可能还会用到.如果还有更好的方法或者算法,希望大家提出来. 1.简单的相似度算法(自己想到的)      因为List中每个String都会包含一个标准的字符 ...

  6. Web Api通过Route、RoutePrefix等特性设置路由

    [Route("customers/{customerId}/orders")] [HttpGet] public IEnumerable<Order> FindOrd ...

  7. Flash与JS之间相互调用以及参数传递

    [AS3]ExternalInterface.call传多个参数的写法代码示例 import flash.text.TextField; ; ; var result:uint = ExternalI ...

  8. HTML静态网页导航制作

    普通导航栏制作 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www ...

  9. Android开发中的问题及相应解决(持续更新)

    最近博客写的少了,以后还得经常更新才行. ------------------------------------------------------------ 1.特定业务需求下try cath ...

  10. 22.python笔记之web框架

    一.web框架本质 1.基于socket,自己处理请求 #!/usr/bin/env python3 #coding:utf8 import socket def handle_request(cli ...