为什么要学习 ECMAScript 协议

前言

ECMAScript标准是深入学习JavaScript原理最好的资料,没有其二。

通过增加对ECMAScript语言的理解,理解javascript现象后面的逻辑,提升个人编码能力。

欢迎关注和订阅专栏 重学前端-ECMAScript协议上篇

一起讨论几个问题

Realm, Agent,Agent Cluster 是什么

  • Realm:主要关注全局对象集和全局执行环境的隔离
  • Agent:关注的是并发执行和执行上下文的管理
  • Agent Cluster: 关注内存共享

其三者的关系图如下

  1. 一个Window对应的有一个Realm, Realm有一个 [[GlobalThis]]属性指向 Window的实例,每个Window的下的内置对象是不同的。

    javascript 复制代码
    const iframe = document.createElement("iframe");
    document.body.appendChild(iframe);
    const xArray = window.frames[window.frames.length - 1].Array;
    
    // 不同领域的Array不相等
    xArray === Array                 // false
  2. 一个Agent 对应有一个 事件循环的线程,一个事件循环可以涉及到多个Realm (Window实例)。 即多个Window实例共享一个事件循环。

    通常情况下,同源下的index.htmliframe.html共用一个事件循环。

    html 复制代码
    // index.html
    <iframe src="./iframe.html"></iframe>
    <script>
        function checkExecution() {
            console.log('Checking execution in index page', new Date().toTimeString());
        }
    
        setInterval(checkExecution, 1000); // 每秒执行一次
    </script>
    
    // iframe.html
    <script>
      function longRunningOperation() {
          const startTime = Date.now();
          let i = 0;
          while (Date.now() - startTime < 5000) { // 假设执行5秒
              i++;
          }
          console.log('Long operation finished in iframe page', new Date().toTimeString());
      }
    
      setTimeout(() => {
          longRunningOperation();
      }, 2000)
    
    </script>
  • index.html 前2000ms每秒输出,
  • 2000ms之后因为iframe.html的阻塞,导致了 index.html暂停了输出,
  • 5000ms之后,又继续输出。
  1. 同源的Window实例可能处于不同Agent,如果没有直接关联。比如

    1. 直接地址栏打开两个页面
    2. rel=noopener打开的新页面

    怎么去验证呢,很简单呢,每个Agent有自己独立的执行线程。使用rel=noopener打开的other.html, other.html的阻塞不影响index.html的输出即可。 这里的 index.html和other.html就属于不同的Agent。

    html 复制代码
    // index.html
    <h1> 同源下的不个Realm(Window)拥有独自的Agent</h1>
      <a href="./other.html" target="_blank" rel="noopener">other页面</a>
      <script>
          function checkExecution() {
              console.log('Checking execution in index page', new Date().toTimeString());
          }
    
          setInterval(checkExecution, 1000); // 每秒执行一次
      </script>
    
    // other.html
    <script>
        // 页面1(或Web Worker1)
        function longRunningOperation() {
            console.log('Long operation started ', new Date().toTimeString());
            const startTime = Date.now();
            let i = 0;
            while (Date.now() - startTime < 5000) { // 假设执行5秒
                i++;
            }
            console.log('Long operation finished ', new Date().toTimeString());
        }
        setTimeout(() => {
            longRunningOperation();
        }, 2000)
    </script>

    看输出结果

    修改 rel="opener" ,结果会怎么样呢?

this是什么

随便提一个问题 this 是什么? 却少有人能够说清楚其来龙去脉, 因为要说清 this, 从协议层面来说至少需要牵涉到

  • 严格模式
  • 函数对象
  • 执行上下文
  • 环境记录(全局环境记录,申明环境记录,函数环境记录,全局环境记录等)
  • 函数绑定特异对象等概念。

其本质: 函数执行时从 环境记录 中临时借用的一个值而已。 且并不是所有的环境记录都可以保存这个 this的绑定关系的值。

其从设置到使用过程又分为

比如如下代码

javascript 复制代码
var obj = {
  log:() => {
    "use strict"
  	return this.eName
  },
  eName: "object eName"
};
obj.log(); // undefined

最终的 this 的查找流程如下:

块是如何 let/const/class 离开之后就不能被访问到的

html 复制代码
<script>
  "use strict"
  var varA = 'varA';
  {
    var varA = 'block_varA';
    function constA(){};
    console.log(varA, constA);    // block_varA   ƒ constA() { }
  }
  console.log(varA, constA);      // Uncaught ReferenceError: constA is not defined

</script>

三张图解释清楚

进入Block之前

Block 内 console.log(varA, constA) 执行前

退出Block后

你会学到什么?

  • ECMAScript协议的一些协议概念,模块章节,进化史等等;
  • 语言类型,协议类型以及一些语法导向的操作
  • 浏览器中环境中 Agent, Realm, Agent Clusters的概念和基本机制;
  • 脚本是怎么从文本到被执行的
  • 执行上下文,环境记录,引用记录,以及她们是怎么协作让标志符运作起来
  • 作用域和作用域链,闭包的底层逻辑
  • 函数对象的初始化,new 的机制
  • 暂时性死区的协议原理,with语句运作机制,申明&赋值&属性赋值的区别
  • 块是怎么生效等
  • 各种运算符以及怪谈的底层逻辑
  • 类型转换的最底层原则
  • ECMAScript 的 Built-in Exotic Object 怪异对象
  • 其他各种协议知识
  • 数组和对象的 快慢机制和基本原理
  • 写代码,理解代码

适宜人群

  • 想完整阅读ECMASCript协议,强化内功,缺乏相关基础的同志;
  • 前端1-3年的初中级前端工程师,想进一步向高级工程师的迈进;
  • 对于JS各种现象和设计,追求知其然知其所以然的JSer;
  • 想要跳槽,攻克技术面试知识点的同学。
相关推荐
_十六几秒前
看完就懂!用最简单的方式带你了解 TypeScript 编译器原理
前端·typescript
Komorebi_99991 分钟前
Axios 是一个基于 Promise 的 HTTP 客户端,可用于浏览器和 Node.js 环境。以下是它的一些主要作用
javascript·ajax
云端看世界1 分钟前
ECMAScript 运算符怪谈 上
前端·javascript·ecmascript 6
前端涂涂2 分钟前
express的介绍,简单使用
前端
正在脱发中3 分钟前
vue-cropper 遇到的坑 Failed to execute 'getComputedStyle' on 'Window': parameter
前端·vue.js
黑暗之神5 分钟前
灵通义码应用课题——基于制作海报demo
前端
前端涂涂7 分钟前
express的中间件,全局中间件,路由中间件,静态资源中间件以及使用注意事项 , 获取请求体数据
前端·后端
新时代农民工--小明8 分钟前
从0开始搭建一套工具函数库,发布npm,支持commonjs模块es模块和script引入使用
前端·javascript·typescript·npm·node.js
云端看世界8 分钟前
ECMAScript 标识符绑定关系和作用域
前端·javascript
云端看世界9 分钟前
ECMAScript 闭包
前端·javascript·ecmascript 6