ES6标准入门(第 3 版)
25.3 数组的空位
阅读(

ECMAScript 6 简介

let 和 const 命令

变量的解构赋值

字符串的扩展

正则的扩展

数值的扩展

函数的扩展

数组的扩展

对象的扩展

Symbol

Set 和 Map 数据结构

Proxy

Reflect对象

Promise对象

Iterator 和 for...of 循环

Generator函数语法

Generator函数的异步应用

async函数

Class的基本语法

Class的继承

Decorator

ES6模块

加载ES6模块

ES6编码规范

读懂ES6规格

概述

相等运算符

数组的空位

下面再看另一个例子。

const a1 = [undefined, undefined, undefined];
const a2 = [, , ,];

a1.length // 3
a2.length // 3

a1[0] // undefined
a2[0] // undefined

a1[0] === a2[0] // true

上面代码中,数组a1的成员是三个undefined,数组a2的成员是三个空位。这两个数组很相似,长度都是 3,每个位置的成员读取出来都是undefined

但是,它们实际上存在重大差异。

0 in a1 // true
0 in a2 // false

a1.hasOwnProperty(0) // true
a2.hasOwnProperty(0) // false

Object.keys(a1) // ["0", "1", "2"]
Object.keys(a2) // []

a1.map(n => 1) // [1, 1, 1]
a2.map(n => 1) // [, , ,]

上面代码一共列出了四种运算,数组a1a2的结果都不一样。前三种运算(in运算符、数组的hasOwnProperty方法、Object.keys方法)都说明,数组a2取不到属性名。最后一种运算(数组的map方法)说明,数组a2没有发生遍历。

为什么a1a2成员的行为不一致?数组的成员是undefined或空位,到底有什么不同?

规格的12.2.5 小节《数组的初始化》给出了答案。

“Array elements may be elided at the beginning, middle or end of the element list. Whenever a comma in the element list is not preceded by an AssignmentExpression (i.e., a comma at the beginning or after another comma), the missing array element contributes to the length of the Array and increases the index of subsequent elements. Elided array elements are not defined. If an element is elided at the end of an array, that element does not contribute to the length of the Array.”

翻译如下。

"数组成员可以省略。只要逗号前面没有任何表达式,数组的length属性就会加 1,并且相应增加其后成员的位置索引。被省略的成员不会被定义。如果被省略的成员是数组最后一个成员,则不会导致数组length属性增加。”

上面的规格说得很清楚,数组的空位会反映在length属性,也就是说空位有自己的位置,但是这个位置的值是未定义,即这个值是不存在的。如果一定要读取,结果就是undefined(因为undefined在 JavaScript 语言中表示不存在)。

这就解释了为什么in运算符、数组的hasOwnProperty方法、Object.keys方法,都取不到空位的属性名。因为这个属性名根本就不存在,规格里面没说要为空位分配属性名(位置索引),只说要为下一个元素的位置索引加 1。

至于为什么数组的map方法会跳过空位,请看下一节。

如果本教程对您帮助很大,请随意打赏。您的支持,将鼓励我们提供更好的教程!

← 键盘方向键翻页 →
返回顶部 手机访问 关注微信 返回底部

扫码访问歪脖网

随时随地,想看就看

关注歪脖网微信

分享 web 知识、交流 web 经验