V8 blog 理解 ECMAScript 规范读后感

271 天前
 royalknight

本人的一个小读后感,读后感原文在博客链接,博客欢迎添加友链

https://blog.myim.online/blog/%E7%90%86%E8%A7%A3ecmascript%E8%A7%84%E8%8C%83/%E7%90%86%E8%A7%A3-ecmascript-%E8%A7%84%E8%8C%83%E8%AF%BB%E5%90%8E%E6%84%9F.html

ECMAScript 规范 链接 https://v8.dev/blog/tags/understanding-ecmascript

水平有限,欢迎指点批评

正文

ECMAScript 规范 这一合集,第一章主要讲了规范中的一些基础语法,注意,这里是规范的语法,

类似于 ! 和 ?,问号比较常用,它的作用类似于解除包装后的值,这一语法挺像 rust 的 Some 去匹配 Option 。

介绍完基本语法,第二章讲了非常实用的一个 js 操作,就是取值。

obj.foo 这个操作经历了什么,文章中是从底向上描述的。

如果是从顶向底描述,则是,obj.foo 这一个字符串先被词法分析器解析,解析之后,获得一个 Reference 对象,这个对象中包含了基值 obj 和键值 foo ,之后就会传给GetValue

GetValue是一个规范内部的方法,接受一个参数 V ,这个参数的类型是一个 Reference ,Reference 中就包含了基值和键值,读这个方法,可以了解 js 的一些基本执行原理,下面是我自己对这个方法的描述;

如果 V 不是 Reference 类型,就直接返回 V ,

获取 Reference 中的 Base ,即基值,然后判断基值是否为原始类型,就是 number ,string 这些,如果是的话,就得把这些类型转为包装类型再调用其方法。如果不是原始类型,就调用`[[Get]]`方法,这个方法需要传入 V 的键值名字,还有一个 Receiver ,

Receiver 是通过 GetThisValue(V)获取的,这里的 GetThisValue ,其实相当于获取 V 的 Base ,基值。

[[Get]] 本身也是一个方法,

[[Get]](P ,Receiver)里面直接调用了?OrdinaryGet(O ,P ,Receiver),所以,直接看看 OrdinaryGet 的实现

OrdinaryGet 中详细定义了取值的规范。

下面我就把重要的过程描述一下:

取 obj 中的 foo 的值的时候,首先看对象本身有没有这个键值,如果没有,就调用 GetPrototypeOf 得到对象的原型,然后再调用原型的`[[Get]](P ,Receiver)`,这里就会产生递归,就会沿着原型链递归的查找键值。

那如果对象本身有这个键值呢?那就直接返回就好了,这里要判断一下,是能直接取到值,还是被 getter 函数包装了,如果被 getter 函数包装了,就再调用一下 getter 函数,然后返回值。这里规范内部调用 getter 的时候,还需要传 Receiver

上面的过程,可以明显看出,整个调用过程的 Receiver 就没变过!

还可以注意到,Receiver 一直传,一直传,传到了哪里?有什么用?

用一个例子来解释下。

看下面的代码:

const o1 = { x: 10, get foo() { return this.x; } };
const o2 = { x: 50 };
Object.setPrototypeOf(o2, o1);
o2.foo;
// → 50

调用 o2.foo 的时候,就找到了一个 o1 的 getter 函数,这里重要了,因为调用的是 getter ,所以调用 getter 方法,

getter 方法传入的 Receiver 就是 o2 ,进入到函数中,再使用 this 时,这里的 this 就是指的 Receiver o2 ,因为上面所说,Receiver 就没变过。

所以,直接得出 o2.foo 的值就是 50 ,而不是 o1 中的 10 。

从这个例子可以看出,规范中的一些定义,可以帮我们理清一些 js 怪异的行为,还是比较有帮助的。

怎么去阅读规范,那就是直接打开网页 https://tc39.es/ecma262/

1507 次点击
所在节点    JavaScript
2 条回复
chnwillliu
254 天前
搭配 super 食用效果更佳,还有 super.xxx = 5 这种左值用法😂
royalknight
253 天前
@chnwillliu 这一点还没看到

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/1018102

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX