深入理解JavaScript-JavaScript 中的始皇

简介: 深入理解JavaScript-JavaScript 中的始皇

前言


笔者在 继承 中发了一题关于原型链关系图的题,题目来源自颜海镜的如何回答面试中的JavaScript原型链问题[1],这题确实很好,当画完它时,会有种看到这幅图的感觉

image.png

确实,这图一看很懵,搞不懂。再来看看这几段代码


Object instanceof Object // true
Function instanceof Function // true
Object instanceof Function // true
Function instanceof Object // true


为什么会如此,Object 和 Function 谁才是始皇,还有 Object.prototype 处于什么位置,Function.prototype 呢?


在知乎曾讨论过这个话题,JS中先有Object还是先有Function?[2]

这里,笔者查一查谁是最先出现的皇


正文


在写 一切皆对象 时,笔者阐释 JavaScript 中的对象有内置对象,而这些内置对象是语言内部创建,这些内置对象都是构造函数,即又被称为内置构造函数,它们存在的目的是为了让开发者更方便的书写代码。这些内置构造函数包括 Object、Function、Array、String、Number、RegExp 等等


因为它们是构造函数,所以它们必然属于函数,因为是函数,所以它们都是 Function 创建的,因为是 Function 创建的,所以它们都是 Function 的实例,即


String instanceof Function // true
Array instanceof Function // true
Function instanceof Function // true
Object instanceof Function // true


所以它们的原型链关系图是

image.png

又因为 Function 是函数,所以它有 prototype 属性。因为函数也是对象,所以 Function 也有 constructor 和 [[Prototype]],它的关系图是

image.png

所以就有了


Function.__proto__ === Function.prototype

即:

image.png

原型 中,我们讲到了原型链,因为每个对象都有[[Prototype]]属性,它会指向它的原型对象,一层一层,最终指向 null。而 null 的上一站是 Object.prototype


无论你是构造函数的原型,还是自定义对象的原型,都会先指向 Object.prototype,再由 Object.prototype 指向 null


String.prototype.__proto__ === Object.prototype // true
Number.prototype.__proto__ === Object.prototype // true
Array.prototype.__proto__ === Object.prototype // true
Function.prototype.__proto__ === Object.prototype // true
Object.prototype.__proto__ === null // true
var obj = {};
var arr = [];
function func() {}
obj.__proto__ ===  Object.prototype // true
arr.__proto__.__proto__ === Object.prototype // true
// arr.__proto__ 指向 Array.prototype
func.__proto__.__proto__ === Object.prototype // true
// func.__proto__ 指向 Function.prototype


它们的原型链关系图如下所示:

image.png

image.png

所以看代码和图我们知道,所有原型继承的源头都在 Object.prototype,Object.prototype 对象上的属性,会被任何值使用,所以判断类型最准确的办法是 Object.prototype.toString.call(source)


如果我们将构造函数的源头和原型的源头结合一下,就成了这样:

image.png

此图和 Object Layout 的图大差不差,关键在于 Object 和 Function

Object.prototype 的原型之母,任何原型都源自它


Function.prototype 是构造函数之母,任何构造函数都由它创建,包括它自己

理解了这两点,我们再回过头看这个问题


Object instanceof Object // true
// Object 由 Function.prototype 创建,Function.prototype 的原型对象指向 Object.prototype
Function instanceof Function // true
// Function 由 Function.prototype 创建
Object instanceof Function // true
// Object 由 Function.prototype 创建
Function instanceof Object // true
// Function 由 Function.prototype 创建,Function.prototype 的原型对象指向Object.prototype


注意一点:构造函数也是实例,找出创建他们的构造函数和原型就能明白


总结


谁是始皇,无疑。Object.prototype 才是真正的始皇,任何原型都源自它;而 Function.prototype 是仅次于 Object.prototype 的存在,它是内置构造函数的创建者,任何构造函数都源自它


参考资料


[1如何回答面试中的JavaScript原型链问题: https://zhuanlan.zhihu.com/p/356980105

[2] JS中先有Object还是先有Function?: https://www.zhihu.com/question/35442532

相关文章
|
2天前
|
云安全 监控 安全
|
7天前
|
机器学习/深度学习 人工智能 自然语言处理
Z-Image:冲击体验上限的下一代图像生成模型
通义实验室推出全新文生图模型Z-Image,以6B参数实现“快、稳、轻、准”突破。Turbo版本仅需8步亚秒级生成,支持16GB显存设备,中英双语理解与文字渲染尤为出色,真实感和美学表现媲美国际顶尖模型,被誉为“最值得关注的开源生图模型之一”。
851 5
|
12天前
|
人工智能 Java API
Java 正式进入 Agentic AI 时代:Spring AI Alibaba 1.1 发布背后的技术演进
Spring AI Alibaba 1.1 正式发布,提供极简方式构建企业级AI智能体。基于ReactAgent核心,支持多智能体协作、上下文工程与生产级管控,助力开发者快速打造可靠、可扩展的智能应用。
1079 40
|
9天前
|
机器学习/深度学习 人工智能 数据可视化
1秒生图!6B参数如何“以小博大”生成超真实图像?
Z-Image是6B参数开源图像生成模型,仅需16GB显存即可生成媲美百亿级模型的超真实图像,支持中英双语文本渲染与智能编辑,登顶Hugging Face趋势榜,首日下载破50万。
642 37
|
12天前
|
人工智能 前端开发 算法
大厂CIO独家分享:AI如何重塑开发者未来十年
在 AI 时代,若你还在紧盯代码量、执着于全栈工程师的招聘,或者仅凭技术贡献率来评判价值,执着于业务提效的比例而忽略产研价值,你很可能已经被所谓的“常识”困住了脚步。
706 60
大厂CIO独家分享:AI如何重塑开发者未来十年
|
8天前
|
存储 自然语言处理 测试技术
一行代码,让 Elasticsearch 集群瞬间雪崩——5000W 数据压测下的性能避坑全攻略
本文深入剖析 Elasticsearch 中模糊查询的三大陷阱及性能优化方案。通过5000 万级数据量下做了高压测试,用真实数据复刻事故现场,助力开发者规避“查询雪崩”,为您的业务保驾护航。
449 28
|
15天前
|
数据采集 人工智能 自然语言处理
Meta SAM3开源:让图像分割,听懂你的话
Meta发布并开源SAM 3,首个支持文本或视觉提示的统一图像视频分割模型,可精准分割“红色条纹伞”等开放词汇概念,覆盖400万独特概念,性能达人类水平75%–80%,推动视觉分割新突破。
923 59
Meta SAM3开源:让图像分割,听懂你的话
|
5天前
|
弹性计算 网络协议 Linux
阿里云ECS云服务器详细新手购买流程步骤(图文详解)
新手怎么购买阿里云服务器ECS?今天出一期阿里云服务器ECS自定义购买流程:图文全解析,阿里云服务器ECS购买流程图解,自定义购买ECS的设置选项是最复杂的,以自定义购买云服务器ECS为例,包括付费类型、地域、网络及可用区、实例、镜像、系统盘、数据盘、公网IP、安全组及登录凭证详细设置教程:
203 114