- js的算术
- js的字符串
- js的布尔值
- debugger和”use strict”
- js的对象
- 对象字面量扩展语法
- 数组
- 数组方法
- forEach()方法迭代数组的每一个元素,并对每个元素都调用一次我们指定的函数。
- map()方法把调用它的数组的每个元素分别传给我们指定的函数,返回这个函数的返回值构成的数组。
- filter()方法返回一个数组,该数组包含调用它的数组的子数组。传给这个方法的函数应该是个断言函数,即返回true或false的函数。
- find()和findIndex()方法寻找断言函数返回真值的元素,这两个方法会在断言函数找到第一个元素时停止迭代。此时,find()返回匹配的元素,findIndex()返回匹配元素的索引,如果没有找到匹配的元素,则find()返回undefined,而findIndex()返回-1。
- every()和some()方法是数组断言方法,即它们会对数组元素调用我们传入的断言函数,最后返回true或false。
- reduce()和reduceRight()方法使用我们指定的函数归并数组元素,最终产生一个值。
- flat()和flatMap()打平数组
- concat()方法创建并返回一个新数组
- push()方法在数组末尾添加一个或多个元素
- pop()方法删除数组最后一个元素并返回该元素,同时导致数组长度减1
- shift()方法删除并返回数组的第一个元素,让数组长度减1并将所有元素移动到低一位
- unshift()方法在数组开头添加一个或多个元素,已有元素的索引会相应向更高索引移动,并返回数组的新长度
- slice()方法接收两个参数,分别是用于指定要返回切片的起止位置。
- splice()是一个可以插入、删除或替换数组元素的通用方法
- fill()方法将数组的元素或切片设置为指定的值,会修改调用它的数组,也返回修改后的数组
- copyWithin()方法把数组切片复制到数组中的新位置。它会就地修改数组并返回修改后的数值,但不会改变数组的长度。
- indexOf()和lastIndexOf()从数组中搜索指定的值并返回第一个找到的元素的索引,如果没有找到则返回-1。
- includes()方法接收一个参数,如果数组包含该值则返回true,否则返回true。
- sort()对数组元素就地排序并返回排序后的数组。
- reverse()方法反转数组元素的顺序,并返回反序的数组,会直接对已经存在的数组进行反序
- join()方法把数组的所有元素转换为字符串,可以指定一个可选的字符串参数,如果不指定则默认是逗号
- toString()方法,逻辑与没有参数的join()方法一样。
- Array.isArray() 传入一个数组,确定未知值是不是数组
- Array.from() 类数组转换
- delete操作符删除数组元素
js的算术
Math对象-支持更复杂的数学计算
Math.pow(2,53) //=> 2的53次方Math.round(.6) //=> 1.0; 舍入到最接近的整数Math.ceil(.6) //=> 1.0; 向上舍入到一个整数Math.floor(.6) //=> 0.0; 向下舍入到一个整数Math.abs(-5) //=> 5; 绝对值Math.max(x,y,z) //返回最大的参数Math.min(x,y,z) //返回最小的参数Math.random() //伪随机数x,其中0 <= x < 1.0Math.PI //π : 圆周率Math.E //e : 自然对数的底数Math.sqrt(3) //=> 3**0.5; 3的平方根Math.pow(3,1/3) //=> 3**(1/3); 3的立方根Math.sin(0) //三角函数;还有Math.cos、Math.atan 等Math.log(10) //10的自然对数Math.log(100)/Math.LN10 //以10为底100的对数Math.log(512)/Math.LN2 //以2为底512的对数Math.exp(3) //Math.E的立方
Math对象-ES6在Math对象上有定义了一批函数:
Math.cbrt(27) //=> 3; 立方根Math.hypot(3,4) //=> 5; 所有参数平方和的平方根Math.log10(100) //=> 2; 以10为底的对数Math.log2(1024) //=> 10; 以2为底的对数Math.log1p(x) //(1+x)的自然对数;精确到非常小的xMath.expm1(x) //Math.exp(x)-1; Math.log1p()的逆运算Math.sign(x) //对<、==或>0的参数返回-1、0或1Math.imul(2,3) //=> 6; 优化的32位整数乘法Math.clz32(0xf) //=> 28; 32位整数中前导0的位数Math.trunc(3.9) //=> 3; 剪掉分数部分得到整数Math.sinh(x) //双曲线正弦,还有Math.cosh() 和 Math.tanh()Math.asinh(x) //双曲线反正弦,还有Math.acosh() 和 Math.atanh()
记录一些Number属性-ES6
Number.isNan(x) //判断x是不是NaNNumber.isFinite(x) //判断x是数值还是无穷Number.isInteger(x) //判断x是不是整数
js的字符串
操作字符串的API
let s = "Hello,world";//取得字符串的一部分s.substring(1,4) //=> "ell"; 第2~4个字符、s.slice(1,4) //=> "ell"; 同上s.slice(-3) //=> "rld"; 最后3个字符//搜索字符串s.indexOf("l") //=> 2; 第一个字母l的位置s.indexOf("l",3) //=> 3; 位置3后面第一个"l"的位置s.indexOf("zz") //=> -1; s并不包含子串"zz"s.lastIndexOf("l") //=> 10; 最后一个字母l的位置//ES6及之后版本中的布尔值搜索函数s.startsWith("Hell") //=> true; 字符串是以这些字符开头的s.endsWith("!") //=> false; s不是以它结尾的s.includes("or") //=> true; s包含子串"or"//创建字符串的修改版本s.replace("llo","yz") //=> "heya,world"; 把llo替换成yzs.toLowerCase() //=> "hello,world"; 英文大写全部转小写s.toUpperCase() //=> "HELLO,WORLD"; 英文小写全部转大写s.normalize() //=> Unicode NFC 归一化:ES6新增s.normalize("NFD") //=> NFD归一化。还有"NFKC"和"NFKD"//访问字符串中的个别(16位值)字符s.charAt(0) //=> "H"; 第一个字符s.charAt(s.length-1) //=> "d"; 最后一个字符s.charCodeAt(0) //=> 72; 指定位置的16位数值s.codePoinAt(0) //=> 72; ES6,适用于码点大于16位的情形//ES2017新增的字符串填充函数"x".padStart(3) //=> " x"; 在左侧添加空格,让字符串长度变成3"x".padEnd(3) //=> "x "; 在右侧添加空格。让字符串长度变成3"x".padStart(3,'*') //=> "**x"; 在左侧添加星号,让字符串长度变成3"x".padEnd(3,'-') //=> "x--"; 在右侧添加破折号,让字符串长度变成3//删除空格函数。trim()是ES5就有的,其他是ES2019增加的" test ".trim() //=> "test"; 删除开头和末尾的空格" test ".trimStart() //=> "test "; 删除左侧空格。也叫trimLeft" test ".trimEnd() //=> " test"; 删除右侧空格。也叫trimRight//未分类字符串方法s.concat("!") //=> "Hello,world!"; 可以用+操作符代替"<>".repeat(5) //=> "<><><><><>"; 拼接n次。ES6新增
正则表达式-RegExp对象
//RegExp对象一些方法let text = "testing: 1, 2, 3"let pattern = /\d+/g // 匹配一个或多个数字pattern.test(text) // => true; 存在匹配项text.search(pattern) // => 9; 第一个匹配项的位置text.match(pattern) // => ["1","2","3"]; 所有匹配项的数组text.replace(pattern,"#") // => "testing: #,#,#"text.split(/\D+/) // => ["","1","2","3"]; 基于非数字拆分
js的布尔值
布尔值有一个toString()方法,可用于将自己转换为字符串”true”或”false”
&&操作符
当且仅当两个操作数都为真时,求值结果才是真;
任何一个操作数为假,结果都为假。
||操作符
任何一个操作数为真,求值结果就是真;
只有当两个操作数均为假时,结果才是假
debugger和”use strict”
debugger
“use strict”
js的对象
删除属性
delete book2.author; book对象现在没有author属性了delete book["main title"]; 现在也没有main title属性了
测试属性
in操作符-要求左边是一个属性名,右边是一个对象。如果对象有包含相应名字的自有属性或继承属性,将返回true
let o = { x: 1 }"x" in o //=> true; o有自有属性"x""y" in o //=> false; o没有属性"y""toString" in o //=> true; o继承了toString属性
枚举属性
Object.keys()返回对象可枚举自有属性名的数组。不包含不可枚举属性、继承属性或名字是符号的属性Object.getOwnPropertyNames()返回对象可枚举自有属性名的数组,但会返回不可枚举自有属性名的数组,只要它们的名字是字符串Object.getOwnPropertySymbols()返回名字是符号的自有属性,无论是否可枚举。Reflect.ownKeys()返回所有属性名,包含可枚举和不可枚举属性,以及字符串属性和符号属性。eObject.assign()接收两个或多个对象作为参数。它会修改并返回第一个参数,第一个参数为目标对象,但不会修改第二个及后续参数,那些都是来源对象。对于每个来源对象,它会把该对象的可枚举自有属性(包括名字为符号的属性)复制到目标对象。它按照参数列表顺序逐个处理来源对象,第一个来源对象的属性会覆盖目标对象的同名属性,而第二个来源对象(如果有)的属性会覆盖第一个来源对象的同命属性。
序列化对象
JSON.stringify() 对象转字符串JSON.parse()字符串转对象
对象字面量扩展语法
简写属性
let x = 1,y = 2;let o = { x , y };o.x + o.y // => 3
计算的属性名
const PROPERTY_NANE = "p1";function computePropertyName() { return "p" + 2; };let p = {[PROPERTY_NANE] : 1,[computePropertyName()] : 2}
符号作为属性名
const extension = Symbol("my extension symbol");let o = {[extension]: { /* 这个对象中存储扩展数据 */ }}o[extension].x = 0; //这个属性不会与o的其他属性冲突//Symbol()工厂函数:不需要new调用,返回值不等于任何其他符号或其他值,给Symbol()传入一个字符串。
扩展操作符
//扩展操作符"..."把已有对象的属性复制到新对象中let position = { x: 0, y: 0}let dimensions = { width: 100, height: 75 };let rect = { ...position, ...dimensions };//如果扩展对象和被扩展对象有一个同命属性,那么这个属性的值由后面的对象决定:let o = { x : 1 };let p = { x: 0, ...o};p.x //=> 1: 对象o的值覆盖了初始值let q = { ...o, x: 2 };q.x //= >2: 对象2覆盖了前面对象o的值//扩展操作符只扩展对象的自由属性,不扩张任何继承属性let o = Object.create({x: 1}); //o继承属性xlet p = { ...o };p.x //=> undefined注意:如果对象有n个属性,把这个属性扩展到另一个对象可能是一种O(n)操作。
简写方法
let square = {area() { return this.side * this.side },side : 10}
属性的获取方法与设置方法
let o = {//一个普通的数据属性dataProp: value,//通过一对函数定义的一个访问器属性get accessorProp(){ return this.dataProp },set accessorProp(){ this.dataProp = value }}
数组
扩展操作符
//简单使用let a = [1, 2, 3];let b = [0, ...a, 4]; // b == [0, 1, 2, 3, 4]//创建数组(浅)副本let original = [1,2,3];let copy = [...original];copy[0] = 0; //修改copy不会影响originaloriginal[0] // => 1//扩展运算符适用任何可迭代对象//(可迭代对象可以使用for/of循环遍历),例如字符串let digits = [..."0123"];digits // => ['0','1','2','3']//集合对象是可迭代的,因此可以这样去除数组中的重复元素//Set是es6新增的数据结构,似于数组,一大特性就是所有元素都是唯一的,没有重复的值,一般我们称为集合let letters = [..."hello world"];[...new Set(letters)] //=>['h','e','l','o',' ','w','r','d']
Array.from()
期待一个可迭代对象或类数组对象作为其第一个参数,并返回包含该对象元素的新数组。
如果传入可迭代对象,Array.from(iterable)与使用扩展操作符[…iterable]一样,因此它也可以创建数组副本。let copy = Array.from(original);
Array.from()还定义了一种给类数组对象创建真正的数组副本的机制。类数组对象不是数组对象,但也有一个数组length对象,而且每个属性的键也都是整数。例如客户端中的querySelectorAll会返回类数组对象。let truearray = Array.from(arraylike);
Array,from()也接受可选的第二个参数。如果给第二个参数传入一个函数,那么在构造新数组时,源对象的每个元素都会传入这个函数,这个函数的返回值将代替原始值成为新数组的元素。
数组长度
每个数组都有length属性。
数组(无论稀疏与否)中任何元素的索引都不会大于或等于数组的length。为了维护这种不变式(invariant),数组有两个特殊行为。
第一:如果给一个索引为i的数组元素赋值,而i大于或等于数组当前的length,则数组的length属性会被设置为i+1。
第二:数组实现以维护长度不变式的第二个特殊行为,就是如果将length属性设置为一个小于其当前值的非负数n,则任何索引大于或等于n的数组元素都会从数组中被删除。
a = [1,2,3,4,5];a.length = 3; //a变成[1,2,3]a.length = 0; //删除所有元素。a是[]a.length = 5; //长度是5,但没有元素,类似new Array(5)
添加和删除数组元素
迭代数组
for/of循环、forEach()方法,老式for循环
//把数组长度保存到局部变量中for(let i = 0,len = letters.length;i < len;i++) {//循环体不变}//从后向前迭代数组for(let i = letters.length-1;i >= 0;i--) {//循环体不变}//如果元素中包含undefinedfor(let i = 0,i < a.length;i++) {if(a[i] === undefined) continue; //跳过未定义及不存在的元素//这里的循环体}
数组方法
forEach()方法迭代数组的每一个元素,并对每个元素都调用一次我们指定的函数。
map()方法把调用它的数组的每个元素分别传给我们指定的函数,返回这个函数的返回值构成的数组。
filter()方法返回一个数组,该数组包含调用它的数组的子数组。传给这个方法的函数应该是个断言函数,即返回true或false的函数。
let a = [5,4,3,2,1];a.filter(x => x < 3) // => [2, 1], 小于3的值a.filter((x,i) => i%2 === 0) // => [5, 3, 1],隔一个选一个//同时,filter()会跳过稀疏数组中缺失的元素,它返回的数组始终是稠密的。//因此可以使用filter()方法清理掉稀疏数组中的空隙let dense = sparse.filter(() => true);//删除值为undefined和null的元素a = a.filter(x => x !== undefined && x !== null);
find()和findIndex()方法寻找断言函数返回真值的元素,这两个方法会在断言函数找到第一个元素时停止迭代。此时,find()返回匹配的元素,findIndex()返回匹配元素的索引,如果没有找到匹配的元素,则find()返回undefined,而findIndex()返回-1。
every()和some()方法是数组断言方法,即它们会对数组元素调用我们传入的断言函数,最后返回true或false。
//every()方法且旨在断言函数对数组的所有元素都返回true时才返回truelet a = [1,2,3,4,5]a.every(x => x < 10) //=> true: 所有值都小10a.every(x => x % 2 === 0) //=> false: 并非所有值都是偶数//some()方法只要数组元素中有一个让断言函数返回true它就返回true,//但必须数组的所有元素对断言函数都返回false才返回falselet a = [1,2,3,4,5]a.some(x => x%2 === 0) //=> true,a包含偶数a.some(isNaN) //=> false,a没有非数值
reduce()和reduceRight()方法使用我们指定的函数归并数组元素,最终产生一个值。
//reduce()接收两个参数。//第一个参数是执行归并操作的函数,这个归并函数的任务就是把两个值归并或组合为一个值。//第二个参数是可选的,是传给归并函数的初始值。let a = [1,2,3,4,5]a.reduce((x,y) => x+y,0) //=> 15;所有值之和a.reduce((x,y) => x*y,1) //=> 120;所有值之积a.reduce((x,y) => (x > y) ? x : y) //=> 5,最大值//reduceRight()与reduce()类似,只不过是从高索引向低索引(从右到左)处理数组。//计算2^(3^4)。求幂具有从右到左的优先级let a = [2, 3, 4];a.reduceRight((acc,val) => Math.pow(val,acc))
flat()和flatMap()打平数组
//flat()方法用于创建并返回一个新数组,这个新数组包含与它调用flat()的数组相同的元素,//只不过其中任何本身也是数组的元素会被"打平"填充到返回的数值中。[1,[2, 3]].flat() //=> [1,2,3][1,[2, [3]]].flat() //=> [1, 2, [3]]//只需给flat()传一个数值参数,即可打平更多层级let a = [1, [2, [3, [4]]]];a.flat(1) //=> [1, 2, [3, [4]]]a.flat(2) //=> [1, 2, 3, [4]]a.flat(3) //=> [1, 2, 3, 4]a.flat(4) //=> [1, 2, 3, 4]//flatMap()方法与map()方法相似,只不过返回的数组会自动被打平,就像传给了flat()一样。let phrases = ["hello world","the definitive guide"];let words = phrases.flatMap(phrase => purase.split(" "));words // => ["hello","world","the","definitive","guide"];
concat()方法创建并返回一个新数组
let a = [1,2,3]a.concat(4,5) //=> [1,2,3,4,5]a.concat([4,5],[6,7]) //=> [1,2,3,4,5,6,7],数组被打平了a.concat(4, [5,[6,7]]) //=> [1,2,3,4,5,[6,7]],但不会打平嵌套的数组a //=> [1,2,3],原始数组没有改变注意,concat()会创建调用它的数组的副本,这样操作代价有点大。
push()方法在数组末尾添加一个或多个元素
pop()方法删除数组最后一个元素并返回该元素,同时导致数组长度减1
shift()方法删除并返回数组的第一个元素,让数组长度减1并将所有元素移动到低一位
unshift()方法在数组开头添加一个或多个元素,已有元素的索引会相应向更高索引移动,并返回数组的新长度
slice()方法接收两个参数,分别是用于指定要返回切片的起止位置。
如果只指定一个参数,返回的数组将包含从该七点开始直到数组末尾的所有元素。如果任何一个参数是负值,则这个值对于数组长度指定数组元素。比如,参数-1指定数组的最后一个元素,参数-2指定倒数第二个元素。
注意,slice()不会修改调用它的数组。
let a = [1,2,3,4,5];a.slice(0,3); // 返回[1,2,3,4]a.slice(3); // 返回[3,4]a.slice(1,-1); // 返回[2,3,4]a.slice(-3,-2); // 返回[3]
splice()是一个可以插入、删除或替换数组元素的通用方法
第一个参数指定插入或删除操作的起点位置。
第二个参数指定要从数组中删除(切割出来)的元素个数。
splice()的前两个参数指定要删除哪些元素。这两个参数后面还可以跟任意多个参数,表示要在第一个参数指定的位置插入到数组的元素。
如果省略第二个参数,从起点元素开始的所有数组元素都将被删除。
splice()返回被删除元素的数组,如果没有删除元素则返回空数组。
let a = [1,2,3,4,5,6,7,8];a.splice(4) //=> [5,6,7,8], a现在是[1,2,3,4]a.splice(1,2) //=> [2,3], a现在是[1,4]a,splice(1,1) //=> [4], a现在是[1]let a = [1,2,3,4,5]a.splice(2,0,"a","b") //=> []; a现在是[1,2,"a","b",3,4,5]a.splice(2,2,[1,2],3) //=> ["a","b"]; a现在是[1,2,[1,2],3,3,4,5]
fill()方法将数组的元素或切片设置为指定的值,会修改调用它的数组,也返回修改后的数组
第一个参数是要把数组元素设置成的值。
第二个参数是可选的,指定起始索引,如果省略则从索引0开始填充。
第三个参数是可选的,指定终止索引,到这个索引为止(但不包含)的数组元素会被填充,也可以传入负值相对于数组末尾指定索引。若省略,则从起始索引开始一直填充到数组末尾。
let a = new Array(5);a.fill(0) //=> [0,0,0,0,0], 用0填充数组a.fill(9, 1) //=> [0,9,9,9,9], 从索引1开始填充a.fill(8, 2, -1) //=> [0,9,8,8,9], 在索引2、3填充8
copyWithin()方法把数组切片复制到数组中的新位置。它会就地修改数组并返回修改后的数值,但不会改变数组的长度。
第一个参数指定要把第一个元素复制到的目的索引。
第二个参数指定要复制的第一个元素的索引。如果省略第二个参数,则默认值为0。
第三个参数指定要复制的元素的的切片的终止索引。如果省略则使用数组的长度。也可以传入负值相对于数组末尾指定索引。
let a = [1,2,3,4,5]a.copyWithin(1) //=> [1,1,2,3,4]: 把数组元素复制到索引1及以后a.copyWithin(2,3,5) //=> [1,1,3,4,4]: 把最后两个元素复制到索引2a.copyWithin(0,-2) //=> [4,4,3,4,4]: 负偏移量也可以
indexOf()和lastIndexOf()从数组中搜索指定的值并返回第一个找到的元素的索引,如果没有找到则返回-1。
indexOf()从前都后搜索数组,而lastIndexOf()从后向前搜索数组
indexOf()和lastIndexOf()都接收第二个可选的参数,指定从哪个位置开始搜索,可省略,第二个参数可以是负值,相对于数组末尾偏移。比如,-1指定数组的最后一个元素。
includes()方法接收一个参数,如果数组包含该值则返回true,否则返回true。
sort()对数组元素就地排序并返回排序后的数组。
//在不传参调用时,sort()按字母顺序对数组元素排序//如果数组包含未定义的元素,它们会被排到数组末尾let a = ["banana","cherry","apple"];a.sort(); //a == ["apple","banana","cherry"]//对数组元素执行非字母顺序的排序,需给sort()传一个比较函数作为参数。let a = [33, 4, 1111, 222];a.sort(); //a == [1111, 222, 33, 5] 字母顺序a.sort(function(a,b){ //传入一个比较函数return a-b; //取决顺序,返回<0、0或>0}); //a == [4, 33, 222, 111],数值顺序a.sort((a,b) => b-a); //a == [1111, 222, 33, 4],相反的数值顺序
reverse()方法反转数组元素的顺序,并返回反序的数组,会直接对已经存在的数组进行反序
join()方法把数组的所有元素转换为字符串,可以指定一个可选的字符串参数,如果不指定则默认是逗号
toString()方法,逻辑与没有参数的join()方法一样。
Array.isArray() 传入一个数组,确定未知值是不是数组
Array.from() 类数组转换
delete操作符删除数组元素
let a = [1,2,3]delete a[2]; //现在索引2没有元素了2 in a //=> false: 数组索引2没有定义a.length //=> 3: 删除元素不影响数组长度
