# javascript悟道读书笔记
大概过一遍《javascript悟道》 这本书,通读了一下,然后记录一下
# js 规范
Q:问题-构造函数和普通函数本身不存在区别,为了给函数划分语义,从而 使一些错误更容易被发现
A:所有的构造函数都应 该以大写字母开头,而其他任何名字都应该以小写字母开头
Q:javascript的保留字
A:arguments await break case catch class const continue debugger default delete do else enum eval export extends false finally for function if implements import in Infinity instanceof interface let NaN new null package private protected public return static super switch this throw true try typeof undefined var void while with yield
# js数值
Q:NaN 居然不等于它自己!
A:NaN 的相等比较与其他数值的相等比较是不一样的,应当使用 Number.isNaN(value)。Number. isFinite(value)函数会在值为 NaN、Infinity 或者-Infinity 的时候返回 false
Q:JavaScript的位运算符
A: JavaScript 中唯一的一元位运算符是波浪号(~),表示“非”运算。
Q:JavaScript的运算 0.1 与0.3
A:JavaScript 不是很擅长处理小数,尤其是与金钱相关的小数。 JavaScript 无法精确表示绝大多数小数,0.1 就是其中之一。
JavaScript 中的整数在进行 乘除操作的时候,只能精确到 53 位。也就是说,我们在数组中存储的每个元素位数不能超过 53 的一半
number 函数则会将高精度整数转换为 JavaScript 的 number 类型。如果入参的大小在安全 整数范围之内,则结果是精确的
string 函数会将高精度整数转换为字符串,其转换结果也是精确的。
# js数组
Q:Array的创建方式
A:1. 数组字面量; 2. new Array(integer)。
Q:Array的如何做道队列
A:通过push与pop方法
```
/**
* 基于数组封装队列类
*
* @returns {*}
* @constructor
*/
export function Queue() {
// 属性
this.items = []
// 方法
// 1.enqueue():将元素加入到队列中
Queue.prototype.enqueue = element => {
this.items.push(element)
}
// 2.dequeue():从队列中删除前端元素
Queue.prototype.dequeue = () => {
return this.items.shift()
}
// 3.front():查看前端的元素
Queue.prototype.front = () => {
return this.items[0]
}
// 4.isEmpty:查看队列是否为空
Queue.prototype.isEmpty = () => {
return this.items.length == 0;
}
// 5.size():查看队列中元素的个数
Queue.prototype.size = () => {
return this.items.length
}
// 6.toString():将队列中元素以字符串形式输出
Queue.prototype.toString = () => {
let resultString = ''
for (let i of this.items){
resultString += i + ' '
}
return resultString
}
// 7.清空队列
Queue.prototype.clearAll = () => {
this.items.length = 0
}
```
Q:遍历的方式
A:forEach 方法将一个函数作用于数组——它将为数组中的每个元素执行一遍传入的函数。 传入的函数可以接收三个参数:element、element_nr 和 array。element 表示当前正在处 理的元素。element_nr 则是当前元素的序号,以备不时之需。array 其实是一个美丽的错误, 真的非常多余。有了它,你有时候就会忍不住去修改数组,但修改正在运算中的数组真的不是一 个明智的举动。
有一点比较遗憾,JavaScript 中并没有一个像 reduceRight 一样可以逆序遍历的方法。如 果你想逆序遍历,可以先调用 reverse 方法,但这个函数具有破坏性,无法用在冻结数组(frozen array)中。
在 forEach 方法中传入的函数,无论返回什么都会被 forEach 忽略。还有一些遍历函数则 会根据传入函数调用时的返回值来做出不同的反应。
every 方法关注其传入函数的返回值。如果传入的函数返回幻假值,every 方法会停止 遍历并直接返回 false;如果传入的函数返回幻真值,every 方法则会继续遍历。遍历完整个数组,every 方法就会返回一个 true。
some 方法与 every 类似。我至今依然困惑:都说一山不容二虎,为什么 JavaScript 还要
让这两个方法共存呢?如果传入的函数返回幻真值,some 会停止遍历并直接返回 true; 如果传入的函数返回幻假值,some 方法则会继续遍历。遍历完整个数组,some 方法会 返回一个 false。
find 方法与 some 类似,只不过最终返回的不是语义上的 true 或者 false,而是当遍 历到函数返回一个幻真值的时候,直接返回当前处理的元素。
findIndex 方法与 find 类似,只不过返回的不是一个元素,而是相应元素的序号。
filter 方法也与 find 类似,只不过返回的是一个新数组,其中依次包含那些遍历处理 时返回幻真值的元素。总的来说,就是 find 返回的是第一次匹配到的元素,而 filter则返回所有的匹配项。
map 方法与 forEach 类似,只不过会将所有经过处理后的元素放到一个新的数组中返回。map 方法是转换元素得出新数组的“神器”。
这一系列方法都是比 for 循环更便捷的利器,只不过这个套装好像还缺点什么。
forEach 和 find 方法都有提前退出的能力(every 和 some 就是 forEach 的可提前退出 形态)。map、reduce 和 filter 则没有这个能力。
reduce 方法有逆序版本 reduceRight,而可怜的 forEach、map、filter 和 find 都 没有这种令人羡慕的逆序版本
Q:连接
A:concat 方法可以将两个或更多数组拼接起来并返回一个新数组
join 方法用分隔符将字符串数组拼接成一个新的字符串,join 其实是字符串 split 方法的逆方法。
reverse 方法会将数组逆序重排。与 sort 方法一样,这个方法也具有破坏性
Q:js数组会改变原数组的一些方法
A:“纯净之树”:
concat
every
filter
find
findIndex
forEach
indexOf
join
lastIndexOf
map
reduce
reduceRight
slice
some
“非纯之树”:
fill
pop
push
shift
splice
unshift
“污染之树”(本该纯净):
reverse
sort
# js对象
Q: 删除某个熟悉
A: 要删除某个属性,正确的做法是使用 delete 运算符。 delete my_little_object["0/0"];
Q: 拷贝
A: Object.assign 函数可以将一个对象中的属性复制到另一个对象中。你可以通过这个函数
来将一个对象复制到一个空对象上。 Q:冻结对象 A: Object.freeze Q:WeakMap A:WeakMap 我们可以安全 地将一个私密属性存储在一个冻结对象中。 他并不允许我们检视对象中的内容。除非拥有对应的键名,否则无法访问其中的内 容。WeakMap 与 JavaScript 的垃圾回收机制可以融洽相处。如果 WeakMap 中的一个键名在外没 有了任何副本,那么这个键名所对应的属性会被自动删除。这可以防止一些潜在的内存泄漏情况
# js 中断
break、continue、throw 和 return。
break 语句用于退出循环。此外,它还可用于退出 switch 语句。但是如果 switch 语句在 循环当中,情况就复杂了。
continue 语句是一种特殊的 goto 语句,用于跳到循环语句的顶部。我见过的所有包含 continue 的程序都能在将其移除后得到优化。
throw 语句用于抛出异常
return。它会中断函数的运行,并指定返回值。学校教导我们, 一个函数只应该有一个 return 语句。然而我从未见过任何证据表明这种理论是有益的。我认为 更有意义的说法应该是在使用 return 的时候确信目前应当返回,而不是将所有的返回点集中到 一处。
# js生成器
```
function* counter() {
let count = 0;
while (true) {
count += 1;
yield count;
}
}
const gen = counter();
gen.next().value
// 1
gen.next().value
// 2
gen.next().value
// 3
```
# 异常
Q:判断异常
A: try{} catch(e){}
Q: 抛出异常
A: threw