【人人都能读标准】13. 对象类型的内部模型

本文为《人人都能读标准》—— ECMAScript篇的第13篇。我在这个仓库中系统地介绍了标准的阅读规则以及使用方式,并深入剖析了标准对JavaScript核心原理的描述。


JavaScript是一门面向对象编程语言,绝大多数的操作都是基于对象完成的。

本节,我会先讲ECMAScript对象的内部模型,这个模型可以帮助我们理解对象的内部行为。然后,我们会使用这个模型来实现类型判断。最后,我会讲基于这个模型,标准是如何对对象进行分类的。


对象的内部模型

在ECMAScript中,每个对象都有自己的内部方法(internal methods) 以及内部插槽(internal slots) 。内部方法表示对象在运行时上的行为,内部插槽则表示对象的状态,你也可以把它们理解为对象内更为底层的方法和属性。“内部”二字表示内部插槽和内部方法都可以使用“规范类型”,且都不能被ECMAScript程序直接访问。在标准中,所有的内部方法和内部插槽都使用[[]]表示。


内部方法

所有的对象都必须有以下的内部方法,这些方法称为基础内部方法(Essential Internal Methods)

基础内部方法 描述
[[GetPrototypeOf]] 获取对象的原型
[[SetPrototypeOf]] 设置对象的原型
[[IsExtensible]] 判断对象是否可以增加新的属性
[[PreventExtensions]] 控制对象是否允许增加新的属性
[[GetOwnProperty]] 返回某个自身属性的属性描述符(Property Descriptor)
[[DefineOwnProperty]] 用一个属性描述符来创建或者修改一个自身属性
[[HasProperty]] 判断对象是否有某个属性
[[Get]] 获取对象的属性
[[Set]] 设置对象属性
[[Delete]] 删除对象属性
[[OwnPropertyKeys]] 获取对象所有的自身属性

从以上列表可以看出,这些都是一些非常基础的操作,用于完成对象属性的增、删、改、查。许多暴露在Object构造器以及Object.prototype上的方法,都是对这些内部方法的封装。比如,用以获得对象原型的静态方法Object.getPrototypeOf(O):

object-getPrototype-of

除了以上的内部方法,对象可能还有两个特殊的内部方法:

  • [[Call]]方法:实现了这个内部方法的对象是函数对象,这个方法会由函数调用表达式触发,并执行一段绑定在对象上的逻辑。关于[[Call]]方法,我们会在14.函数中进行深入研究。
  • [[Construct]]方法:实现了这个内部方法的对象是构造器对象,这个方法由new表达式或super方法触发,会创建一个新的对象。关于[[Construct]]方法,我们会在15.类中进行深入研究。

内部插槽

最重要的内部插槽是[[Prototype]],该插槽指向另一个对象或者null。当对象A的[[Prototype]]指向对象B时,B即为A的原型对象。此时,对A来说,A自身的属性称为自有属性(own properties) ,而B的属性都为A的继承属性(inherit properties) 。当然,B也有自己的[[Prototype]]。于是,所有通过[[Prototype]]连接起来的对象就构成了A的原型链。

除了[[Prototype]],常见的内部插槽还有:

  • [[Extensible]]:用来表示对象是否可扩展。当这个插槽值为false时,对象不能添加属性、不能修改[[prototype]]插槽、不能修改[[Extensible]]插槽为true。这个插槽可以使用Object.isExtensible(Obj)Object.preventExtensions(Obj)间接访问与修改。
  • [[privateElements]]:用于存储对象上的私有属性方法。

应用:类型判断

基于对象内部方法以及内部插槽,我们可以完成一些类型判断的工作。主要有两种思路:

  1. 基于对象特有的内部插槽或内部方法,判断对象的类型。
  2. 基于[[Prototype]]内部插槽,判断对象的类型。

我在12.原始类型中提到过,在原始类型上调用方法,会使得原始类型通过抽象操作ToObject转化为特定的对象,而原始类型对应的每一种对象,都有自己特有的内部插槽。比如布尔对象有一个特有的[[BooleanData]]内部插槽,Number对象有一个特有的[[NumberData]]内部插槽。。。因而,我们可以根据这些特有的内部插槽识别出数据类型。

当然,我们无法直接访问内部插槽,但是有的语言API会帮助我们间接完成访问,比如

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值