学习笔记 2020-10-11
JavaScript 高级程序设计(第4版) 阅读记录
集合引用类型
Array
转换方法
let colors = ['red', 'blue', 'green']; console.log(colors.toString()); // red,blue,green console.log(colors.valueOf()); // ["red", "blue", "green"] console.log(colors); // ["red", "blue", "green"]
toString
方法本质是返回数组中每个值的等效字符串加逗号分隔拼接成的字符串let person1 = { toLocaleString () { return 'Sirine'; }, toString () { return 'Sirine'; } } let person2 = { toLocaleString () { return 'Severus'; }, toString () { return 'siruis'; } } let people = [person1, person2]; console.log(people); // [{…}, {…}] console.log(people.toString()); // Sirine,siruis console.log(people.toLocaleString()); // Sirine,Severus
由上例可以看出,
toString
方法调用自身的toString
来转换,toLocaleString
调用自身的toLocaleString
。栈方法
后进先出的数据结构,数据的推入和删除只发生在栈顶。
push
接收任意数量的参数,将它们添加到数组末尾,返回数组的最新长度。
pop
用于删除数组的最后一项,减少数组的长度,返回被删除的项。
队列方法
先进先出的数据结构,末尾添加数据,开头获取数据。
shift
返回被删除的项。
push
unshift
与
shift
相反,在数组开头添加任意数量的值,返回新的数组长度。
排序方法
以下两个方法都返回调用的数组的引用。
reverse
反向排列数组。
sort
排序数组。默认按照升序,每一项调用
String
转换,比较字符串决定顺序。也可以接受一个比较函数,函数的返回值决定每两个数比较的排序情况,返回负值代表第一个数排在第二个前面,返回0
代表相等,返回正值代表第一个数排在第二个后面。
操作方法
concat
在原有数组基础上创建一个新数组,将参数添加到数组末尾。不改变原数组。返回新数组。
concat
默认会打平数组参数,即传入的数组参数会被展开。设置数组的Symbol.isConcatSpreadable
可以修改这个行为。如下例所示:let colors = ['red', 'green', 'blue']; let newColors = ["black", "brown"]; let moreNewColors = {
[Symbol.isConcatSpreadable]: true,
length: 2,
0: “pink”,
1: “cyan”
};
newColors[Symbol.isConcatSpreadable] = false;
// 强制不打平数组
let colors2 = colors.concat(“yellow”, newColors);
// 强制打平类数组对象
let colors3 = colors.concat(moreNewColors);
console.log(colors); // [“red”, “green”, “blue”]
console.log(colors2); // [“red”, “green”, “blue”, “yellow”,[“black”, “brown”]]
console.log(colors3); // [“red”, “green”, “blue”, “pink”, “cyan”]
slice
接收一到二个参数,返回元素的开始索引和结束索引,若只提供了开始索引,会默认返回到数组末尾。返回的数组不包括结束索引(若存在)对应的元素。不影响原数组。这个函数的参数接受负值,代表从末尾开始。若结束位置小于开始位置,返回空数组。
splice
有三种不同的使用方式,返回值为被删除的元素或是空数组。
删除
传递两个参数,删除的第一个元素位置以及删除的数量。
插入
传递三个参数,开始位置,
0
和插入的元素,不仅限于三个参数,多于三个的参数都会被看作用于插入的元素。替换
在删除的同时插入新元素,即插入的另一种模式,不再是删除
0
个元素。
let colors = ['red', 'green', 'blue']; let removed = colors.splice(0, 1); console.log(colors); // ["green", "blue"] console.log(removed); // ["red"] removed = colors.splice(1, 0, 'yellow', 'orange'); console.log(colors); // ["green", "yellow", "orange", "blue"] console.log(removed); // [] removed = colors.splice(1, 1, 'red', 'purple'); console.log(colors); // ["green", "red", "purple", "orange", "blue"] console.log(removed); // ["yellow"]
搜索和位置方法
indexOf
lastIndexOf
includes
上述三个方法都接收两个参数,要查找的元素和一个可选的起始位置。并且三个方法都是严格相等比较。
indexOf
和includes
从数组前头开始搜索,lastIndexOf
从末尾开始搜索。indexOf
和lastIndeOf
返回查找的位置或是-1
,includes
返回true
或false
表示是否找到至少一个匹配的元素。find
findIndex
上述两个方法接收断言函数和一个可选的断言函数内部
this
的值,断言函数接收三个参数,元素、索引和数组本身。断言函数返回真值,代表是否匹配。find
返回第一个匹配的元素,findIndex
返回第一个匹配元素的索引。找到匹配项后,都不再继续搜索。
迭代方法
以下方法都对数组每一项运行传入的函数。不改变原数组。
every
若每一项使得函数返回值都为
true
, 那么这个方法返回true
。filter
函数返回值为
true
的项组成一个数组返回。forEach
没有返回值,仅对每一项运行函数。
map
返回每一项函数调用的结果构成的函数。
some
有一项使得函数返回值为
true
, 方法返回true
。
现代 JavaScript 教程
switch 语句
switch
语句可以替代if
判断,执行严格相等比较。switch
和case
允许任意表达式。let a = "1"; let b = 0; switch (+a) { case b + 1: alert("this runs, because +a is 1, exactly equals b+1"); break; default: alert("this doesn't run"); }
case
分组let a = 3; switch (a) { case 4: alert('Right!'); break; case 3: // (*) 下面这两个 case 被分在一组 case 5: alert('Wrong!'); alert("Why don't you take a math class?"); break; default: alert('The result is strange. Really.'); }
任务:
将
switch
结构重写为if
结构将下面
switch
结构的代码写成if..else
结构:switch (browser) { case 'Edge': alert( "You've got the Edge!" ); break; case 'Chrome': case 'Firefox': case 'Safari': case 'Opera': alert( 'Okay we support these browsers too' ); break; default: alert( 'We hope that this page looks ok!' ); }
if (browser === 'Edge') { alert("You've got the Edge!"); } else if (browser === 'Chrome' || browser === 'Firefox' || browser === 'Safari' || browser === 'Opera') { alert( 'Okay we support these browsers too' ); } else { alert( 'We hope that this page looks ok!' ); }
将
if
结构重写为switch
结构用
switch
重写以下代码:let a = +prompt('a?', ''); if (a == 0) { alert( 0 ); } if (a == 1) { alert( 1 ); } if (a == 2 || a == 3) { alert( '2,3' ); }
let a = +prompt('a?', ''); switch(a) { case 0: alert(0); break; case 1: alert(1); break; case 2: case 3: alert('2,3'); break; }
JavaScript 深入学习
错误类型
SyntaxError
语法错误,例如变量名不规范不合法。
var 1 = 1; // Uncaught SyntaxError: Unexpected number var a = 1 = 2; // Uncaught SyntaxError: Invalid left-hand side in assignment
ReferenceError
变量或函数未声明。
a(); // Uncaught ReferenceError: a is not defined
RangeError
范围出错。
let arr = [1, 2, 3]; arr.length = -1; // Uncaught RangeError: Invalid array length let num = new Number(66.66); console.log(num.toFixed(-1)); // Uncaught RangeError: toFixed() digits argument must be between 0 and 100
TypeError
类型错误。
123(); // Uncaught TypeError: 123 is not a function
URIError
URI: uniform resource identifier 统一资源标识符
URL: uniform resource locator 统一资源定位符
URN: uniform resource name 统一资源名称
var str = decodeURI('%abcde'); // Uncaught URIError: URI malformed at decodeURI (<anonymous>)
try catch
try {
var json = JSON.parse(jsonStr);
} catch (e) {
// 出现错误时捕获错误。
console.log(e);
} finally {
// 无论出错与否都会执行
}
throw
手动抛出错误。
严格模式
严格模式下 with
callee
caller
无法使用。
函数内部的 this
默认值为 undefined
。需要显式指定。
使用 call
这类方法改变 this
指向时,如果传入的是原始值,会被包装为包装类。
函数的参数不允许重复。
对象的键不允许重复,但不报错,只会默认覆盖。
eval
内存在一个作用域,外部无法访问内部变量。
TODO-LIST
- 想尝试一下
hugo
作为博客。 - 整理 18 年的笔记。