核心代码,注释必读
// download:3w 52xueit com
vue 2.x 响应式
Object.defineProperty
爱学it学无止境
不知道大家有没有这种感觉,日常开发中,总觉的对javascript的知识掌握的很多,但是想系统的梳理一下JS的知识体系,又觉得繁杂的无从下手,每次下定决心开始梳理,中途就不了了之了,这是第N次开始梳理JS,区别前几次暗自整理笔记,这次采用以公开的技术文章的方式梳理,希望能得到一些正反馈,让我能坚持的久一些。。。
本次梳理过的设想的是从JS对象开始整理,这种原理性内容一般都是比较乏味的,我写起来乏味,大伙读起来也发乏味,因此决定每篇文章的内容不会很长,但会很精炼。废话不多说,废话又说了很多,接下来是正文。
前置提醒: JS ( Javascript )和 ES ( ECMAScript )之分
JS是由网景公司开发的主要用于浏览器的脚本语言,当时取名Javascript(据说是为了蹭当时已经很火的?java的热度),为了标准化,交由ECMA国际标准化组件做标准化管理,从而诞生了ECMA-262标准化规范,称为ECMAScript。可以理解为ES是JS标准化后的版本,从研究的方向上考虑,ES和JS有很多不同,如果想了解具体区别,请自行查阅相关资料,为了行文方便,本篇文章对这两个概念做了混淆处理,统一用JS称呼。
这是本系列的第一篇文章,众所周知,在JS中,对象是一等公民,万物皆对象。那么JS是如何定义和管理对象的行为的呢? 接下来浅谈一下对这个问题的理解。
内部方法、内部槽以及抽象操作的概念
内部方法和内部槽整体可以理解为是对 js 对象内部行为的抽象,分开讲:
内部方法:可以理解为是对js对象内部行为的抽象,当开发者在js语法层面对一个对象进行操作的时候,js引擎内部实际会调用对应的内部方法完成对应操作。一个js对象的实际语义是由内部方法定义的。
示例:
内部槽:可以理解是js对象内部对当前对象状态的抽象,比如,在js中,每个普通对象都有一个内部槽[[Extensible]],其值是一个boolean类型,用来指示当前对象是否可扩展(可扩展指的是,能否向该对象添加属性)。
在ECMAScript规范文档中,内部方法和内部槽表示为:[[xxx]]
通常来说内部方法定义了一个js对象在语义上的 原子操作,所谓语义上的原子操作(后面简称原子操作) ,是指对象在语义上的单个行为描述,比如有如下对象:
let obj = {
a:123
}
当我们使用obj.a来读取obj对象的a属性的值时,js引擎内部会通过[[Get]]这个内部方法来读取属性值,因为[[Get]]内部方法只是对读取对象属性值这一单独行为的定义,因此这是一次原子操作。而内部槽定义了一个js对象内部的单个状态。
由原子操作的概念,引出了抽象操作的概念:
抽象操作:由一系列原子操作和内部槽构成的操作,即,一次抽象操作会调用多个内部方法和内部槽。
理清了上面的概念,可以说,在JS中,一个对象的行为和能力是由内部方法和内部槽定义的。对于js开发者而言,无论是内部方法还是内部槽,亦或者抽象操作,均无法直接调用。
PS:之所以强调原子操作是指语义上的原子操作,是因为在ECMAScript文档中,一些内部方法的执行机制,也会调用其它抽象操作,比如,对于[[GetPrototypeOf]]内部方法,其执行时,实际会调用OrdinaryGetPrototypeOf这一抽象操作,而OrdinaryGetPrototypeOf抽象操作内部实际直接返回的是[[Prototype]]内部槽指定的状态值。为了更严谨一些,在原子操作前面加上语义上的限定语,表示内部方法的行为是指语义描述上的单次行为,这一单次行为有可能由多个实际执行步骤实现的。
普通对象(Ordinary Object)和异质对象(Exotic Object)
在JS中,所有的对象其实就分为两类:
普通对象:普通对象包含特定的内部方法和内部槽
异质对象:除了普通对象以外的对象均为异质对象
领取专属 10元无门槛券
私享最新 技术干货