15条规则解析JavaScript对象布局(__proto__、prototype、constructor)
大家都说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对象之间的关系已经了如指掌了,确实一开始我也让这货搞得头晕晕的,但是画出这张图之后已经觉得没什么了。大家可以自己动手画一下。
原文地址:请点击这里
总结(补充):
- 普通函数的原型是由Object()构造器构造的,同Object.prototype一样是Object()构造器的一个实例
- 普通函数是Function()构造器构造的,同Function.prototype一样是Function()构造器的一个实例
- 内部原型链_proto_属性是为了实现继承而存在的,这样,我们可以处于任何目的来修改constructor属性,而不用担心实例与父类的一致性。
15条规则解析JavaScript对象布局(__proto__、prototype、constructor)的更多相关文章
- javascript--15条规则解析JavaScript对象布局(__proto__、prototype、constructor)
大家都说JavaScript的属性多,记不过来,各种结构复杂不易了解.确实JS是一门入门快提高难的语言,但是也有其他办法可以辅助记忆.下面就来讨论一下JS的一大难点-对象布局,究竟设计JS这门语言的人 ...
- 彻底搞懂js __proto__ prototype constructor
在开始之前,必须要知道的是:对象具有__proto__.constructor(函数也是对象固也具有以上)属性,而函数独有prototype 在博客园看到一张图分析到位很彻底,这里共享: 刚开始看这图 ...
- 8条规则图解JavaScript原型链继承原理
原形链是JS难点之一,而且很多书都喜欢用一大堆的文字解释给你听什么什么是原型链,就算有图配上讲解,有的图也是点到为止,很难让人不产生疑惑. 我们先来看一段程序,友情提示sublimeText看更爽: ...
- JavaScript对象原型写法区别
体现对象原型分步式写法 //原型分步式写法 //构造函数 function Person(){} //对象原型 Person.prototype.name = 'Avensatr'; Pers ...
- JavaScript对象原型写法详解
体现对象原型分步式写法 //原型分步式写法 //构造函数 function Person(){} //对象原型 Person.prototype.name = 'Avensatr'; Pers ...
- JavaScript对象创建,继承
创建对象 在JS中创建对象有很多方式,第一种: var obj = new Object(); 第二种方式: var obj1 = {};//对象直面量 第三种方式:工厂模式 function Per ...
- 面向面试编程——javascript对象的几种创建方式
javascript对象的几种创建方式 总共有以下几个模式: 1.工厂模式 2.构造函数模式 3.原型模式 4.混合构造函数和原型模式 5.动态原型模式 6.寄生构造函数模式 7.稳妥构造函数模式 1 ...
- JavaScript大杂烩4 - 理解JavaScript对象的继承机制
JavaScript是单根的完全面向对象的语言 JavaScript是单根的面向对象语言,它只有单一的根Object,所有的其他对象都是直接或者间接的从Object对象继承.而在JavaScript的 ...
- javascript如何解析json对javascript如何解析json对象并动态赋值到select列表象并动态赋值到select列表
原文 javascript如何解析json对象并动态赋值到select列表 JSON(JavaScriptObject Notation)一种简单的数据格式,比xml更轻巧.JSON是JavaScri ...
随机推荐
- git的初步使用
1.在GitHub上建立项目登录GitHub后,你可以在右边靠中那里找到一个按钮“New Repository”,点击过后,填入项目名称.说明和网址过后就可以创建了,然后会出现一个提示页面,记下类似g ...
- 企业该如何进行高效IT运维管理
企业该如何进行高效IT运维管理 在企业内部也是一样,当大量的生产和经营数据集中在数据中心,一旦人们与数据中心因为IT故障而失去联系,停滞的也许不是个人应用受阻这样简单的后果.我们谁也不想看到自己企业的 ...
- Effective Objective-C 2.0之Note.03(属性详解)
用Objective-C等面向对象语言编程时,“对象”(object)就是“基本构造单元”(building block),开发者可以通过对象来存储并传递数据.在对象之间传递数据并执行任务的过程就叫做 ...
- ASP.NET MVC掉过的坑_MVC初识及MVC应用程序结构
APS.Net MVC 浅谈[转] 来自MSDN 点击访问 MVC 理论结构 模型-视图-控制器 (MVC) 体系结构模式将应用程序分成三个主要组件:模型.视图和控制器. ASP.NET MVC 框架 ...
- STL学习三:deque容器
1.Deque简介 deque是“double-ended queue”的缩写,和vector一样都是STL的容器,deque是双端数组,而vector是单端的. deque在接口上和vector非常 ...
- Hadoop TextInputFormat源码分析
from:http://blog.csdn.net/lzm1340458776/article/details/42707047 InputFormat主要用于描述输入数据的格式(我们只分析新API, ...
- JPA学习---第十一节:JPA中的多对多双向关联实体定义与注解设置及操作
1.定义实体类,代码如下: (1).学生实体类: package learn.jpa.entity; import java.util.HashSet; import java.util.Set; i ...
- sudo配置临时取得root权限
系统中的普通用户有时需要root权限执行某种操作,要是使用su - root的话必须要知道root的密码,这是不安全的,所以有了sudo,root可以对/etc/sudoers做一定的配置,让普通用户 ...
- JAVABEAN EJB POJO区别
1.POJO POJO(Plain Old Java Object)这种叫法是Martin Fowler.Rebecca Parsons和Josh MacKenzie在2000年的一次演讲的时候提出来 ...
- android开发连接wifi addNetwork 返回-1
如下代码:(注释掉的是会返回-1的代码,未注释的是能够正常连接wifi的代码) // public WifiConfiguration CreateWifiInfo(String SSID, Stri ...