JavaScript 核心原理解析
周爱民
《JavaScript 语言精髓与编程实践》作者,南潮科技(Ruff)首席架构师
32699 人已学习
新⼈⾸单¥59
登录后,你可以任选3讲全文学习
课程目录
已完结/共 28 讲
开篇词 (1讲)
JavaScript 核心原理解析
15
15
1.0x
00:00/00:00
登录|注册

17 | Object.setPrototypeOf(x, null):连Brendan Eich都认错,但null值还活着

从下一讲开始,将会讨论“动态语言”的相关主题
原子对象可以被理解为关联数组,如果有一个称为“length”的属性,则可以被理解为索引数组
任何一个对象都可以通过特定语法变成原子对象,可以被理解为关联数组或索引数组
代理对象是接管一个对象的原子行为,将它转发给被代理行为处理
JavaScript的对象有且仅有13个原子行为,包括操作原型、属性表和函数行为
一般函数/构造器也可以创建原子对象
类可以派生自null,使得类的实例具有原子特性
原子对象是“对象”的最原始的形态,其特点是“原型为null”
没有属性表的对象称为null
ECMAScript约定了null值是一个原始值,与上述描述有冲突
Null是一个类型,且null是它唯一的值
null值是一个对象类型,用于表达一个对象不存在
null值的出现是有一定的道理的,与JavaScript的类型系统相关
JavaScript中的null值被认为是一个对象
下一步
知识回顾
原子行为
派生自原子的类
属性表
Null类型
null值
JavaScript中的null值设计

该思维导图由 AI 生成,仅供参考

你好,我是周爱民。欢迎回来继续学习 JavaScript。
今天是关于面向对象的最后一讲,上次已经说过,今天这一讲要讨论的是原子对象。关于原子对象的讨论,我们应该从null值讲起。
null值是一个对象。

null 值

很多人说 JavaScript 中的null值是一个 BUG 设计,连 JavaScript 之父 Eich 都跳出来对 Undefined+Null 的双设计痛心疾首,说null值的特殊设计是一个“抽象漏洞(abstraction leak)”。这个东西什么意思呢?很难描述,基本上你可以理解为在概念设计层面(也就是抽象层)脑袋突然抽抽了,一不小心就写出这么个怪胎。
然而我却总是觉得不尽如此,因为如果你仔细思考过 JavaScript 的类型系统,你就会发现null值的出现是有一定的道理的(当然 Eich 当年脑子是不是这样犯的抽抽也未为可知)。怎么讲呢?
早期的 JavaScript 一共有 6 种类型,其中 number、string、boolean、object 和 function 都是有一个确切的“值”的,而第 6 种类型Undefined定义了它们的反面,也就是“非值”。一般讲 JavaScript 的书大抵上都会这么说:
确认放弃笔记?
放弃后所记笔记将不保留。
新功能上线,你的历史笔记已初始化为私密笔记,是否一键批量公开?
批量公开的笔记不会为你同步至部落
公开
同步至部落
取消
完成
0/2000
荧光笔
直线
曲线
笔记
复制
AI
  • 深入了解
  • 翻译
    • 英语
    • 中文简体
    • 中文繁体
    • 法语
    • 德语
    • 日语
    • 韩语
    • 俄语
    • 西班牙语
    • 阿拉伯语
  • 解释
  • 总结

JavaScript中的null值并非BUG设计,而是一个合理的设计。在JavaScript中,null值是一个对象类型,用于表达一个对象不存在的情况,即“非对象”。这使得JavaScript存在两套类型系统,即值类型和对象类型,从而产生了所谓的值类型的包装类和对象的`valueOf()`原型方法。同时,Null类型也是一个类型,且null是它唯一的值。在JavaScript中,null值是一个原始值,是所有对象类型的“元类型”,即一个原子。原子对象是“对象”的最原始形态,其特点是原型为null,代表关联数组的最基础抽象数据结构。JavaScript的对象有且仅有13个原子行为,这使得代理对象能够无缝且全面地代理任何对象。文章还提到了关于原子对象的方法以及代理对象的陷阱方法。总的来说,本文介绍了JavaScript中null值的设计及其在类型系统中的重要地位,以及原子对象和代理对象的相关知识。文章还展望了下一讲将会讨论“动态语言”,为读者提供了对JavaScript语言设计的初步了解。

仅可试看部分内容,如需阅读全部内容,请付费购买文章所属专栏
《JavaScript 核心原理解析》
新⼈⾸单¥59
立即购买
登录 后留言

全部留言(10)

  • 最新
  • 精选
  • 行问
    多看看技术在历史上是怎么出现的,怎么解决问题的,溯源这种“原型链”让我大呼过瘾。一路学习下来,有完全不懂,有闻所未闻,有懵逼,有茅塞顿开等。今天的这一讲,让我理解了 "null" 在实际开发中的合理运用。

    作者回复: ^^ 多谢多谢。能讲得对大家有用就好。:)

    2019-12-23
    12
  • 程序员劝退师
    这是除了加餐课外,我能最快理解的一节课,嗯一定是我进步了😁

    作者回复: 一定是进步了+1 😃

    2019-12-26
    3
  • 小炭
    “原子对象” 这一概念只有Javascript才会有吗,在C和C ++的标准术语也有这个“原子对象” 的定义。不知道他们之间有什么区别,或者这个定义的源头来自哪里?

    作者回复: 从ecmascript来说,也没有原子对象这个概念。我之所以提到这个,是因为“原子性”这个概念可以用在这里,表明这种对象是“原子性的”。如果你有兴趣读一下《JavaScript语言精髓与编程实践(第三版)》,会对这个概念,以及由此带来的一个类型体系有更深的了解。 我最早看到这个概念是在李战的《悟透Delphi》这本书中,我记得后来这本书并没有出版。大概是在那个时间点前后,程序员圈子里兴起过一阵关于“语言原子性”的讨论。 又,这已经是快20年前的事情了。

    2020-11-10
    2
  • 蛋黄酱
    > 如果 MyClass.prototype 指向 null,而 super 指向一个有效的父类,其结果如何呢 这配上示例代码,意思是说setPrototypeOf虽然字面上的意思是改变prototype但本质上只改变了super执行的对象? 我觉得不对吧?

    作者回复: 一共影响三个东西,一个是MyClass和MyClass.prototype中所有方法的super指向,二个是使MyClass的创建过程与super(例如这里的Date)动态绑定起来,三个是MyClass自己的类方法(静态方法)。只不过第三个没有表现在示例中。 这里用setPrototypeOf()改的是MyClass的原型,而不是MyClass.prototype的原型。

    2020-03-15
    2
    2
  • 卡尔
    老师,我记得有一本书里说,undefined派生于null。老师这句话怎么去理解,他俩到底是什么关系?有什么区别?

    作者回复: 那本书一定写错了。 这两者没有直接的关系。在ECMA的概念上,二者都是原始值(primitive values);在JavaScript的概念上,null是对象,而undefined是值(类型)的数据。无论是哪一种理解,二者都没有派生或类属的关系。 关于二者的更多区别,还是建议看一下绿皮书,专门有一节来讨论这个问题。

    2021-01-12
  • HoSalt
    class A {} class B extends A {} B.__proto__ === A // true B.__proto__.__proto__ === Function.prototype // true class MyClass extends null {} MyClass.__proto__ === Function.prototype // true 老师继承自null的类的原型链直接指向了Function.prototype,而其它的是在中间加了一层,这是一种特殊处理?

    作者回复: 这是因为MyClass本来就是一个函数,它的原型(缺省)指向Function.prototype是正常的。 X.prototype不应当是一个null值——对于JS来说,置null值是“无效值”。当这个值无效时(例如null/undefined),等义于它使用Object.prototype。你试着找一个其它对象来试一下就知道了。 X.prototype存在无效值的原因是:缺省情况下,这个属性是可写的。因为“对象属性”在历史中可以写成任何值,所以历史上它就没有“属性类型”这样的限制。这是一个继承历史而来的设计。

    2020-05-25
  • 新哥
    是时候讲一下 prototype和__proto__了😄
    2020-06-21
  • t86
    老师的功力真的是深,佩服
    2020-01-16
  • 水木年华
    老师讲的真好,有体会有收获😄
    2020-01-05
  • 许童童
    老师讲得太好了。
    2019-12-24
收起评论
显示
设置
留言
10
收藏
沉浸
阅读
分享
手机端
快捷键
回顶部