博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
由一段代码引发的关于Object和Function的鸡和蛋问题的思考
阅读量:7052 次
发布时间:2019-06-28

本文共 3310 字,大约阅读时间需要 11 分钟。

作为一名前端开发者,我们都知道JS是单继承的,而Object.prototype是原型链的顶端,所有对象从它继承了包括toString()、valueOf()等等公共属性。

鸡和蛋问题的由来

首先ObjectFunction都是构造函数,而所有的构造函数都是Function的实例对象。 因此ObjectFunction的实例对象;而Function.prototypeObject的实例对象。所以这里就引伸出了一个有意思的鸡和蛋的问题:

Object instanceof Function  // trueFunction instanceof Object  // trueObject.__proto__ === Function.prototype  // trueFunction.__proto__ === Function.prototype  // trueFunction.prototype.__proto__ === Object.prototype  // true复制代码

那么ObjectFunction,谁是鸡谁是蛋呢?

接下来就来深入探究下上面这段代码所引起的鸡生蛋蛋生鸡问题,从下面这张原型/原型链经典图入手,在这个过程中深入了解 Object.prototypeFunction.prototypefunction Object()function Function() 之间的关系,这个过程可能有点烧脑,毕竟是JS的一大玄学嘛。

Object.prototype

原型链的尽头就是Object.prototype(不考虑 null 的情况下)。所有对象均从Object.prototype继承toString() 等公共属性

Object.prototype 表示 Object 的原型对象,实际上Object.prototype 并不是通过Object函数创建的,为什么呢?看如下代码:

function Dog() {  this.name = '川普';}var dog = new Dog();dog.__proto__ === Dog.prototype;  // true复制代码

实例对象的__proto__会指向构造函数的prototype,即dog.__proto__指向 Dog.prototype,但是Object.prototype.__proto__又是 null,所以 Object.prototype 并不是通过 Object 函数创建的,那它如何生成的?其实 Object.prototype 是浏览器底层根据 ECMAScript 规范创造的一个对象,所以在经典图里面只是看起来Object.prototype 是通过 Object 函数创建的,实际上并不是。

Function.prototype

Function.prototypeFunction.__proto__同一对象

这也意味着:Object/Array等等构造函数本质上和Function一样,均继承于Function.prototype,从经典图上来看都是通过new Function构造出来的

当然,Function.prototype 对象是一个函数(对象),其__proto__属性指向 Object.prototype,即Function.prototype会直接继承root(Object.prototype)。

通过这点我们可以弄清继承的原型链Function|Object|Array...--->Function.prototype--->Object.prototype(root)。如下图所示:

function Object()

Object 作为构造函数时,其__proto__属性指向 Function.prototype,即:

Object.__proto__ === Function.prototype  // true复制代码

从经典图来看:

使用 new Object() 创建实例对象o1时,实例对象o1的 __proto__属性指向构造函数的 prototype 属性,对应上图就是 Object.prototype,即o1.__proto__ === Object.prototype结果为true

Function.prototype指向的对象,它的__proto__会指向Object.prototype,因为Function.prototype指向的对象也是一个普通的被Object创建的对象,所以也遵循基本的规则。

function Function()

Function也是一个函数对象,也有__proto__属性,既然是函数,那么它一定是被Function创建,所以Function是被自身创建的,所以它的__proto__指向了自身的Prototype

Function.__proto__ === Function.prototype  // true复制代码

到这里就有点烧脑了吧,我们再看下鸡生蛋蛋生鸡问题。

Function & Object 鸡和蛋问题

由上面可知,Object构造函数继承了Function.prototype,同时Function构造函数继承了Object.prototype,这里就产生了鸡和蛋的问题。为什么会出现这种问题呢?必须首先更深入一层去理解Function.prototype这个对象,因为它是导致Function instanceof ObjectObject instanceof Function都为true的原因。

// Object instanceof Function 	即Object.__proto__ === Function.prototype   // true// Function instanceof Object 	即Function.__proto__.__proto__ === Object.prototype   // true// Object instanceof Object 		即 			Object.__proto__.__proto__ === Object.prototype   // true// Function instanceof Function 即	Function.__proto__ === Function.prototype   // true复制代码

根据JS规范,Function.prototype又是个不同于一般函数(对象)的函数(对象),其中:

  1. Function.prototype像普通函数一样可以调用,但总是返回undefined
  2. 普通函数实际上是Function的实例,即普通函数继承于Function.prototype。即func.__proto__ === Function.prototype
  3. Function.prototype继承于Object.prototype,并且没有prototype这个属性。
  4. 所以,Function.prototype其实是个另类的函数,可以独立于/先于Function产生。

Object本身是个(构造)函数,是Function的实例,即Object.__proto__就是Function.prototype

总结:先有Object.prototype(原型链顶端),Function.prototype继承Object.prototype而产生,最后,FunctionObject和其它构造函数继承Function.prototype而产生

看到这里估计也都看烦了,是不是还是有点混乱呀?乱也很正常。那这篇文章就先让它乱着,下一篇我们将请另一个老朋友来帮忙,把它彻底理清楚,这位老朋友就是——instanceof,那就且听请下回分解咯。

如果觉得文章对你有些许帮助,欢迎在点赞和关注,感激不尽!

转载地址:http://zrvol.baihongyu.com/

你可能感兴趣的文章
10个你应该了解的Git命令(以及Git省时小窍门)
查看>>
Cesium入门9 - Loading and Styling Entities-加载和样式化实体
查看>>
node.js学习笔记三(安装外部node.js模块)
查看>>
我的友情链接
查看>>
Web应用系统开发课程(Jsp程序设计)资源列表
查看>>
浅谈微博营销公司的组织架构
查看>>
MDK4.23调试LPC1114时JLINK的设置
查看>>
SystemCenter2012SP1实践(8)私有云WEB平台SCAC
查看>>
SystemCenter2012SP1实践(30)P2V,从物理机迁移到虚拟机
查看>>
Netty4实现Websocket网页间聊天
查看>>
检测USB是否连接PC
查看>>
关于spring项目的单例测试
查看>>
如何让service被管理器杀死后自动重启
查看>>
理解 OpenStack + Ceph (5):OpenStack 与 Ceph 之间的集成 [OpenStack Integration with Ceph]...
查看>>
获取Teradata表访问频率信息
查看>>
angular 选择删除 小功能
查看>>
openstack_kilo+centos7创建Centos6.6镜像
查看>>
JS(正则)判断是(1)否为邮箱格式;(2)输入框中是否包含中文
查看>>
编程思想之递归
查看>>
BBS小项目的学习与总结
查看>>