前言:
此文章记录了我的调研过程,所以使用了STAR法则进行书写。感兴趣的朋友可以跟着我的调研过程走一遍,体验一下ECMAScript文档的阅读过程。
背景(Situation):
最近在背面试题, 「2021」高频前端面试题汇总之JavaScript篇(上) - 掘金 (juejin.cn)
其中,如下这题,我找了许多博客和MDN文档。但是,关于“类数组对象”和“数组对象”这两个概念的定义,出处,特性,这些资料都并没有给出很好的答案。
题目:“12. 为什么函数的 arguments 参数是类数组而不是数组?如何遍历类数组?”
目标(Target):
- 找出“类数组对象”和“数组对象”这两个概念的定义(必须是最权威的资料),以及这两个概念的出处
- 比对这两种对象的区别
行动(Action):
目标分析:
【问题】如何确保我得到的答案是权威的,正确的一手资料?
【解决方案】我们知道JS(Javascript)是ECMAScript标准的一个具体实现,也就是说,JS最权威的语言规范,就是ECMAScript标准,所以,应该去查阅ECMAScript标准。
ECMAScript® 2021 Language Specification (ecma-international.org)
具体步骤:
在ECMAScript规范中,进行查找
查找方式:在ECMAScript左上角搜索框内搜索“Array”关键字
【知识点】ECMAScript的搜索框会返回4种类型的检索结果,下面对其简单介绍
- term “项”,一般是对一些特定的概念的定义
- op “抽象操作”,是js解释器定义的一些解释器内部使用的操作,比如这里的ArrayCreate(创建数组)
- prod “文法产生式”,编译原理的一个术语。文法产生式就是描述一门编程语言的语法的一套规则。
- clause “条款”,指的是ECMAScript的一个条款
【回顾我们的目标】我们当前目标是“找到‘类数组对象’和‘数组对象’的定义”,所以我们需要“term”这个类型的检索结果,那么,我们已经得到了我们想要的搜索结果
其中,“array-like-object”这个检索结果指向“类数组对象”的定义,“Array exotic object”这个检索结果指向“数组对象”的定义
逐步分析“类数组对象”和“数组对象”
数组的定义:
【英文】:Array exotic object
【位置】:
10.4.2 Array Exotic Objects 此章节第二段
An object is an Array exotic object (or simply, an Array object) if its [[DefineOwnProperty]] internal method uses the following implementation, and its other essential internal methods use the definitions found in 10.1. ****These methods are installed in ArrayCreate.
【分析】:
通过这段话,我们了解到 Array exotic object才是广义上的“Array object”,
而认定一个object是Array object的标准是:
- 它必须拥有ArrayCreate这个抽象操作为它安装的所有函数
- 这个object的[[DefineOwnProperty]]是10.4.2.1 [[DefineOwnProperty]] ( P, Desc )的步骤。
- 由“These methods are installed in ArrayCreate ”这句话我们能推理得出,因为初始化一个Array对象时,必定调用了ArrayCreate,所以,一个这个对象的prototype必定背ArrayCreate设置为 %Array.prototype%
类数组的定义:
【英文】: array-like object
【位置】:
7.3.18 LengthOfArrayLike ( obj )此章节最后一句话
An array-like object is any object for which this operation(this operation指的是LengthOfArrayLike 操作) returns an integer rather than an abrupt completion.
【分析】:
只要一个对象调用LengthOfArrayLike 抽象操作能够返回“integer”而不是“abrupt completion”(也就是意味着这个对象拥有length属性),那么这个对象就是“类数组对象”。
【问题】ArrayCreate到底为Array对象设置了多少方法呢(Array object比Array-like-object多了多少方法)?
【问题分析】Array对象的主要方法,来自于 %Array.prototype% 这个原型(ArrayCreate创建Array对象的时候,指定了对象原型为 %Array.prototype% )。
因为“array like object”并不一定需要其原型为%Array.prototype%。
【解决方案】我们可以点击”ArrayCreate抽象操作”中的“%Array.prototype%超链接” 跳转到 23.1.3 Properties of the Array Prototype Object 章节,在此章节找出 Array Prototype Object 拥有哪些“数组有,而类数组对象没有”的方法。
【结论】Array object拥有Concat() copyWithin,filter,find,findIndex等等方法