JavaScript 高级程序设计第 6 章——集合引用类型学习笔记
Posted GoldenaArcher
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了JavaScript 高级程序设计第 6 章——集合引用类型学习笔记相关的知识,希望对你有一定的参考价值。
javascript 高级程序设计第 6 章——集合引用类型学习笔记
这章内容很长,一些子内容,例如数组,也单独拆分了一章笔记,希望每份笔记的复习时间能够控制在 5-10 分钟左右。
本章的内容包含了:对象,数组,Map, WeakMap, Set 以及 WeakSet。
因为平常业务定型数组使用的不多,需求——嵌入式或是 WebGL 这方面——也不多,所以暂时略过。
对象
显式地创建 Object 的实例有两种方式:
-
使用
new
操作符和构造函数const person = new Object(); person.name = "John"; person.age = 18;
-
直接使用对象字面量
const person = { name: "John", age: 18, };
两个语法都创建了一个名为 person
的对象。
除此之外,在字面量中,属性名也可以是字符串或者是数值,如:
const person = {
"first name": "John",
"last name": "Doe",
age: 18,
6: 666,
};
console.log(person["first name"]);
当然,在这种情况下,取值就要用中括号的语法了。除了字符串和数字之外,中括号中还能传入变量名,这也是最常用的用法:
for (key in person) {
console.log(person[key]);
}
通常来说,使用字面量的情况更加频繁一些,一来是因为结构更加的清晰,二来,在大多数直接使用 对象 的情况下,我们一般都在获取结构简单的数据,其中并不涉及到复杂的原型链、函数之类的调用,在 What’s the difference between “Array()” and “[]” while declaring a JavaScript array? 中,有人解释了使用字面量不会调用构造函数,而是会创造运行时对象(在这个情况下是数组),省去了调用构造函数、创建对象所必须的函数体的步骤,因此效率会高一些。
但是,在 What is the difference between new Object()
and object literal notation? 中也提到了,如果对象中有创建函数的话,字面量对象会在运行时不断地创建新的同样的函数,而使用构造函数,v8 引擎会创建一个构造类,对象与对象之间可以共享隐藏类的函数。因此,使用构造函数的效率会高一些。
当然,也能说这是 v8 引擎的特性,不过我总归是相信其他的解释器也会或多或少的对这个部分进行优化的。
v8 引擎的部分 Stack Overflow 上并没有说,是我结合在 JavaScript 高级程序设计第四章学习笔记 中的学习部分加上去的,具体的在内存管理中的 隐藏类 部分有提到。
感觉知识点都串联起来了,果然,学习的过程中还是要复习一下,知识点记得才会更牢。
总之,日常在拉取数据的时候,使用字面量的情况总归是多过使用构造函数的,毕竟正常情况下为了性能也不太会出现重复拉取数据的情况。
数组
还挺长的,笔记放在了这里:JavaScript 数组详解
数组的运用范围应该说是和对象不分轩轾,谁上谁下也不好说,毕竟正常情况下都是数组套用对象,或是对象套用数组,很少出现单独只使用数组或对象的情况。
其中我觉得在学习数组过程中有种大开眼界的写法还是关于 reduce
的 pipeline 使用案例:
function increment(input) {
return input + 1;
}
function decrement(input) {
return input - 1;
}
function double(input) {
return input * 2;
}
function halve(input) {
return input / 2;
}
// 其他的文件里面可以将 pipeline 作为一个常量进行抽离
const pipeline = [increment, double, decrement];
// 另一个函数中返回 pipeline 的操作值,以前可能要用 arguments 去获取一个伪数组,然后再通过循环去调用 pipeline 里的函数,通过 reduce 代码就能简洁很多
function processPipeline(pipeline, initialValue) {
return pipeline.reduce((accumulator, currentFunc) => {
return currentFunc(accumulator);
}, initialValue);
}
// 某处有数据需要进入 pipeline
const fakeData = [1, 3, 5, 7, 9];
// 处理数据
fakeData.map((val) => processPipeline(pipeline, val)); // [1.5, 3.5, 5.5, 7.5, 9.5]
reduce
的学习案例在 JavaScript 中 reduce 及 6 个使用案例 中,不管怎么说,用了 reduce
实现 pipeline 的代码干净了不少。
定型数组
目的是为了提升向原生库传输数据的功率,因为其他的原生库——尤其是不用 JavaScript 实现的库——多数情况下不是动态数组,这种情况下,JavaScript 传一个动态数组过去。其他的原生库为了兼容 JavaScript 的这个特性,可能就需要额外的检查,并且将动态格式的数组转化成合适的静态格式的数组,这就造成了非常大的性能上的流失。
定型数组有三种格式:
- ArrayBuffer
- DataView
- 定型数组
基于目前没有什么原生库的使用,这一块做个了解,暂时略过。
如果使用 WebGL 的,或是做嵌入式的,还是需要对这方面有一定程度上的了解为好。
其实有过后端语言开发经验的,大概能从 ArrayBuffer 这里看出定型数组是做什么得了吧。
Map 与 Set 相关
还挺长的,笔记放在了这里:JavaScript 中的 Map, Set, WeakMap, WeakSet,其中要注意 WeakMap 的使用案例:拟态私有变量以及绑定 DOM 节点。
迭代与扩展操作
数组、定型数组、Map 和 Set 都有迭代器的实现,因此可以轻松地使用迭代函数,包括但不限于 for-of
, 扩展操作符 ...
,构造函数中传入一个可迭代对象进行实例化,Array.of()
,Array.from()
的使用等。
使用 扩展操作符 就可以轻松且简单的完成浅拷贝:
const arr = [1, 2, 3, ["another arr"], 4];
const shallowCopy = [...arr];
// (5) [1, 2, 3, Array(1), 4]
参考
以上是关于JavaScript 高级程序设计第 6 章——集合引用类型学习笔记的主要内容,如果未能解决你的问题,请参考以下文章