JavaScript高级程序设计基础(十一)

上接语言基础:JavaScript高级程序设计基础(十)

五、集合引用类型

5.1 object

此处简单介绍object,object由两种方式可以创造:由构造函数new Object(),或者对象字面量。如果想要修改对象的值可以用点语法,如object.name="123",如果属性名含有可能会导致语法错误的字符,可以使用中括号,如object["my name"]="123"。

5.2 Array

5.2.1 创建数组

Array 构造函数还有两个ES6新增的用于创建数组的静态方法:from()和of()。from()用于将类数组结构转换为数组实例,而of()用于将一组参数转换为数组实例。

javascript 复制代码
// 字符串会被拆分为单字符数组 
console.log(Array.from("Matt")); // ["M", "a", "t", "t"]  
// 可以使用from()将集合和映射转换为一个新数组 
const m = new Map().set(1, 2) 
                   .set(3, 4); 
const s = new Set().add(1) 
                   .add(2) 
                   .add(3) 
                   .add(4); 
console.log(Array.from(m)); // [[1, 2], [3, 4]] 
console.log(Array.from(s)); // [1, 2, 3, 4] 
// Array.from()对现有数组执行浅复制 
const a1 = [1, 2, 3, 4]; 
const a2 = Array.from(a1); 
console.log(a1);        // [1, 2, 3, 4] 
alert(a1 === a2); // false 
// arguments 对象可以被轻松地转换为数组 
function getArgsArray() { 
  return Array.from(arguments); 
} 
console.log(getArgsArray(1, 2, 3, 4)); // [1, 2, 3, 4]

Array.from()还接收第二个可选的映射函数参数。这个函数可以直接增强新数组的值,还可以接收第三个可选参数,用于指定映射函 数中this的值。但这个重写的this值在箭头函数中不适用

javascript 复制代码
const a1 = [1, 2, 3, 4]; 
const a2 = Array.from(a1, x => x**2); 
const a3 = Array.from(a1, function(x) {return x**this.exponent}, {exponent: 2}); 
console.log(a2);  // [1, 4, 9, 16] 
console.log(a3);  // [1, 4, 9, 16] 

Array.of()可以把一组参数转换为数组

javascript 复制代码
console.log(Array.of(1, 2, 3, 4)); // [1, 2, 3, 4] 
console.log(Array.of(undefined));  // [undefined] 

5.2.2 数组空位

使用数组字面量初始化数组时,可以使用一串逗号来创建空位(hole),ES6新增方法普遍将这些空位当成存在的元素,只不过值为undefined:

javascript 复制代码
const options = [1,,,,5]; 
for (const option of options) { 
  console.log(option === undefined);  
} 
// false 
// true 
// true 
// true 
// false

由于行为不一致和存在性能隐患,因此实践中要避免使用数组空位。如果确实需要空位,则可以显式地用undefined值代替。

5.2.3 数组索引

数组length 属性的独特之处在于,它不是只读的。通过修改length属性,可以从数组末尾删除或添加元素

javascript 复制代码
let colors = ["red", "blue", "green"]; // 创建一个包含3 个字符串的数组 
colors.length = 2; 
alert(colors[2]);  // undefined
colors.length = 4; 
alert(colors[3]);  // undefined 

位置3在数组中不存在,因此访问其值会返回特殊值undefined。

5.2.4 检测数组

一个经典的ECMAScript问题是判断一个对象是不是数组。在只有一个网页(因而只有一个全局作用域)的情况下,使用instanceof操作符就足矣:

javascript 复制代码
if (value instanceof Array){ 
  // 操作数组 
} 

使用instanceof 的问题是假定只有一个全局执行上下文。如果网页里有多个框架,则可能涉及两个不同的全局执行上下文,那么构造函数就会有差别。为解决这个问题,ECMAScript提供了Array.isArray()方法。

javascript 复制代码
if (Array.isArray(value)){  
  // 操作数组 
} 

5.2.5 迭代器方法

keys()返回数组索引的迭代器,values()返回数组元素的迭代器,而 entries()返回索引/值对的迭代器

javascript 复制代码
const a = ["foo", "bar", "baz", "qux"]; 
// 因为这些方法都返回迭代器,所以可以将它们的内容 
// 通过Array.from()直接转换为数组实例 
const aKeys = Array.from(a.keys()); 
const aValues = Array.from(a.values()); 
const aEntries = Array.from(a.entries()); 
console.log(aKeys);     // [0, 1, 2, 3] 
console.log(aValues);   // ["foo", "bar", "baz", "qux"] 
console.log(aEntries);  // [[0, "foo"], [1, "bar"], [2, "baz"], [3, "qux"]] 

使用ES6的解构可以非常容易地在循环中拆分键/值对:

javascript 复制代码
const a = ["foo", "bar", "baz", "qux"]; 
for (const [idx, element] of a.entries()) { 
  alert(idx);  
  alert(element); 
} 
// 0 
// foo 
// 1 
// bar 
// 2 
// baz 
// 3 
// qux

5.2.6 复制和填充方法

fill()方法可以向一个已有的数组中插入全部或部分相同的值

javascript 复制代码
const zeroes = [0, 0, 0, 0, 0];  
// 用5 填充整个数组 
zeroes.fill(5); 
console.log(zeroes);  // [5, 5, 5, 5, 5] 
zeroes.fill(0);       // 重置 
// 用6 填充索引大于等于3的元素 
zeroes.fill(6, 3); 
console.log(zeroes);  // [0, 0, 0, 6, 6] 
zeroes.fill(0);       // 重置 
// 用7 填充索引大于等于1且小于3的元素 
zeroes.fill(7, 1, 3); 
console.log(zeroes);  // [0, 7, 7, 0, 0]; 
zeroes.fill(0);       // 重置 

copyWithin()会按照指定范围浅复制数组中的部分内容,然后将它们插入到指定索引开始的位置

javascript 复制代码
// 从ints 中复制索引0开始的内容,插入到索引5开始的位置 
// 在源索引或目标索引到达数组边界时停止 
ints.copyWithin(5); 
console.log(ints);  // [0, 1, 2, 3, 4, 0, 1, 2, 3, 4] 
reset(); 
// 从ints 中复制索引5开始的内容,插入到索引0开始的位置 
ints.copyWithin(0, 5); 
console.log(ints);  // [5, 6, 7, 8, 9, 5, 6, 7, 8, 9] 
reset(); 
// 从ints 中复制索引0开始到索引3结束的内容 
// 插入到索引4开始的位置 
ints.copyWithin(4, 0, 3); 
alert(ints);  // [0, 1, 2, 3, 0, 1, 2, 7, 8, 9] 
reset(); 

5.2.7 转换方法

如果数组中某一项是null或undefined,则在join()、toLocaleString()、 toString()和 valueOf()返回的结果中会以空字符串表示。

相关推荐
旧味清欢|9 分钟前
关注分离(Separation of Concerns)在前端开发中的实践演进:从 XMLHttpRequest 到 Fetch API
javascript·http·es6
热爱编程的小曾26 分钟前
sqli-labs靶场 less 8
前端·数据库·less
gongzemin37 分钟前
React 和 Vue3 在事件传递的区别
前端·vue.js·react.js
Apifox1 小时前
如何在 Apifox 中通过 Runner 运行包含云端数据库连接配置的测试场景
前端·后端·ci/cd
-代号95271 小时前
【JavaScript】十四、轮播图
javascript·css·css3
树上有只程序猿1 小时前
后端思维之高并发处理方案
前端
庸俗今天不摸鱼2 小时前
【万字总结】前端全方位性能优化指南(十)——自适应优化系统、遗传算法调参、Service Worker智能降级方案
前端·性能优化·webassembly
QTX187302 小时前
JavaScript 中的原型链与继承
开发语言·javascript·原型模式
黄毛火烧雪下2 小时前
React Context API 用于在组件树中共享全局状态
前端·javascript·react.js
Apifox2 小时前
如何在 Apifox 中通过 CLI 运行包含云端数据库连接配置的测试场景
前端·后端·程序员