js的算术

Math对象-支持更复杂的数学计算

  1. Math.pow(2,53) //=> 2的53次方
  2. Math.round(.6) //=> 1.0; 舍入到最接近的整数
  3. Math.ceil(.6) //=> 1.0; 向上舍入到一个整数
  4. Math.floor(.6) //=> 0.0; 向下舍入到一个整数
  5. Math.abs(-5) //=> 5; 绝对值
  6. Math.max(x,y,z) //返回最大的参数
  7. Math.min(x,y,z) //返回最小的参数
  8. Math.random() //伪随机数x,其中0 <= x < 1.0
  9. Math.PI //π : 圆周率
  10. Math.E //e : 自然对数的底数
  11. Math.sqrt(3) //=> 3**0.5; 3的平方根
  12. Math.pow(3,1/3) //=> 3**(1/3); 3的立方根
  13. Math.sin(0) //三角函数;还有Math.cos、Math.atan 等
  14. Math.log(10) //10的自然对数
  15. Math.log(100)/Math.LN10 //以10为底100的对数
  16. Math.log(512)/Math.LN2 //以2为底512的对数
  17. Math.exp(3) //Math.E的立方

Math对象-ES6在Math对象上有定义了一批函数:

  1. Math.cbrt(27) //=> 3; 立方根
  2. Math.hypot(3,4) //=> 5; 所有参数平方和的平方根
  3. Math.log10(100) //=> 2; 以10为底的对数
  4. Math.log2(1024) //=> 10; 以2为底的对数
  5. Math.log1p(x) //(1+x)的自然对数;精确到非常小的x
  6. Math.expm1(x) //Math.exp(x)-1; Math.log1p()的逆运算
  7. Math.sign(x) //对<、==或>0的参数返回-1、0或1
  8. Math.imul(2,3) //=> 6; 优化的32位整数乘法
  9. Math.clz32(0xf) //=> 28; 32位整数中前导0的位数
  10. Math.trunc(3.9) //=> 3; 剪掉分数部分得到整数
  11. Math.sinh(x) //双曲线正弦,还有Math.cosh() 和 Math.tanh()
  12. Math.asinh(x) //双曲线反正弦,还有Math.acosh() 和 Math.atanh()

记录一些Number属性-ES6

  1. Number.isNan(x) //判断x是不是NaN
  2. Number.isFinite(x) //判断x是数值还是无穷
  3. Number.isInteger(x) //判断x是不是整数

js的字符串

操作字符串的API

  1. let s = "Hello,world";
  2. //取得字符串的一部分
  3. s.substring(1,4) //=> "ell"; 第2~4个字符、
  4. s.slice(1,4) //=> "ell"; 同上
  5. s.slice(-3) //=> "rld"; 最后3个字符
  6. //搜索字符串
  7. s.indexOf("l") //=> 2; 第一个字母l的位置
  8. s.indexOf("l",3) //=> 3; 位置3后面第一个"l"的位置
  9. s.indexOf("zz") //=> -1; s并不包含子串"zz"
  10. s.lastIndexOf("l") //=> 10; 最后一个字母l的位置
  11. //ES6及之后版本中的布尔值搜索函数
  12. s.startsWith("Hell") //=> true; 字符串是以这些字符开头的
  13. s.endsWith("!") //=> false; s不是以它结尾的
  14. s.includes("or") //=> true; s包含子串"or"
  15. //创建字符串的修改版本
  16. s.replace("llo","yz") //=> "heya,world"; 把llo替换成yz
  17. s.toLowerCase() //=> "hello,world"; 英文大写全部转小写
  18. s.toUpperCase() //=> "HELLO,WORLD"; 英文小写全部转大写
  19. s.normalize() //=> Unicode NFC 归一化:ES6新增
  20. s.normalize("NFD") //=> NFD归一化。还有"NFKC"和"NFKD"
  21. //访问字符串中的个别(16位值)字符
  22. s.charAt(0) //=> "H"; 第一个字符
  23. s.charAt(s.length-1) //=> "d"; 最后一个字符
  24. s.charCodeAt(0) //=> 72; 指定位置的16位数值
  25. s.codePoinAt(0) //=> 72; ES6,适用于码点大于16位的情形
  26. //ES2017新增的字符串填充函数
  27. "x".padStart(3) //=> " x"; 在左侧添加空格,让字符串长度变成3
  28. "x".padEnd(3) //=> "x "; 在右侧添加空格。让字符串长度变成3
  29. "x".padStart(3,'*') //=> "**x"; 在左侧添加星号,让字符串长度变成3
  30. "x".padEnd(3,'-') //=> "x--"; 在右侧添加破折号,让字符串长度变成3
  31. //删除空格函数。trim()是ES5就有的,其他是ES2019增加的
  32. " test ".trim() //=> "test"; 删除开头和末尾的空格
  33. " test ".trimStart() //=> "test "; 删除左侧空格。也叫trimLeft
  34. " test ".trimEnd() //=> " test"; 删除右侧空格。也叫trimRight
  35. //未分类字符串方法
  36. s.concat("!") //=> "Hello,world!"; 可以用+操作符代替
  37. "<>".repeat(5) //=> "<><><><><>"; 拼接n次。ES6新增

正则表达式-RegExp对象

  1. //RegExp对象一些方法
  2. let text = "testing: 1, 2, 3"
  3. let pattern = /\d+/g // 匹配一个或多个数字
  4. pattern.test(text) // => true; 存在匹配项
  5. text.search(pattern) // => 9; 第一个匹配项的位置
  6. text.match(pattern) // => ["1","2","3"]; 所有匹配项的数组
  7. text.replace(pattern,"#") // => "testing: #,#,#"
  8. 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

  1. let o = { x: 1 }
  2. "x" in o //=> true; o有自有属性"x"
  3. "y" in o //=> false; o没有属性"y"
  4. "toString" in o //=> true; o继承了toString属性

枚举属性

Object.keys()返回对象可枚举自有属性名的数组。不包含不可枚举属性、继承属性或名字是符号的属性
Object.getOwnPropertyNames()返回对象可枚举自有属性名的数组,但会返回不可枚举自有属性名的数组,只要它们的名字是字符串
Object.getOwnPropertySymbols()返回名字是符号的自有属性,无论是否可枚举。
Reflect.ownKeys()返回所有属性名,包含可枚举和不可枚举属性,以及字符串属性和符号属性。
eObject.assign()接收两个或多个对象作为参数。它会修改并返回第一个参数,第一个参数为目标对象,但不会修改第二个及后续参数,那些都是来源对象。对于每个来源对象,它会把该对象的可枚举自有属性(包括名字为符号的属性)复制到目标对象。它按照参数列表顺序逐个处理来源对象,第一个来源对象的属性会覆盖目标对象的同名属性,而第二个来源对象(如果有)的属性会覆盖第一个来源对象的同命属性。

序列化对象

JSON.stringify() 对象转字符串
JSON.parse()字符串转对象

对象字面量扩展语法

简写属性

  1. let x = 1,y = 2;
  2. let o = { x , y };
  3. o.x + o.y // => 3

计算的属性名

  1. const PROPERTY_NANE = "p1";
  2. function computePropertyName() { return "p" + 2; };
  3. let p = {
  4. [PROPERTY_NANE] : 1,
  5. [computePropertyName()] : 2
  6. }

符号作为属性名

  1. const extension = Symbol("my extension symbol");
  2. let o = {
  3. [extension]: { /* 这个对象中存储扩展数据 */ }
  4. }
  5. o[extension].x = 0; //这个属性不会与o的其他属性冲突
  6. //Symbol()工厂函数:不需要new调用,返回值不等于任何其他符号或其他值,给Symbol()传入一个字符串。

扩展操作符

  1. //扩展操作符"..."把已有对象的属性复制到新对象中
  2. let position = { x: 0, y: 0}
  3. let dimensions = { width: 100, height: 75 };
  4. let rect = { ...position, ...dimensions };
  5. //如果扩展对象和被扩展对象有一个同命属性,那么这个属性的值由后面的对象决定:
  6. let o = { x : 1 };
  7. let p = { x: 0, ...o};
  8. p.x //=> 1: 对象o的值覆盖了初始值
  9. let q = { ...o, x: 2 };
  10. q.x //= >2: 对象2覆盖了前面对象o的值
  11. //扩展操作符只扩展对象的自由属性,不扩张任何继承属性
  12. let o = Object.create({x: 1}); //o继承属性x
  13. let p = { ...o };
  14. p.x //=> undefined
  15. 注意:如果对象有n个属性,把这个属性扩展到另一个对象可能是一种O(n)操作。

简写方法

  1. let square = {
  2. area() { return this.side * this.side },
  3. side : 10
  4. }

属性的获取方法与设置方法

  1. let o = {
  2. //一个普通的数据属性
  3. dataProp: value,
  4. //通过一对函数定义的一个访问器属性
  5. get accessorProp(){ return this.dataProp },
  6. set accessorProp(){ this.dataProp = value }
  7. }

数组

扩展操作符

  1. //简单使用
  2. let a = [1, 2, 3];
  3. let b = [0, ...a, 4]; // b == [0, 1, 2, 3, 4]
  4. //创建数组(浅)副本
  5. let original = [1,2,3];
  6. let copy = [...original];
  7. copy[0] = 0; //修改copy不会影响original
  8. original[0] // => 1
  9. //扩展运算符适用任何可迭代对象
  10. //(可迭代对象可以使用for/of循环遍历),例如字符串
  11. let digits = [..."0123"];
  12. digits // => ['0','1','2','3']
  13. //集合对象是可迭代的,因此可以这样去除数组中的重复元素
  14. //Set是es6新增的数据结构,似于数组,一大特性就是所有元素都是唯一的,没有重复的值,一般我们称为集合
  15. let letters = [..."hello world"];
  16. [...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的数组元素都会从数组中被删除。

  1. a = [1,2,3,4,5];
  2. a.length = 3; //a变成[1,2,3]
  3. a.length = 0; //删除所有元素。a是[]
  4. a.length = 5; //长度是5,但没有元素,类似new Array(5)

添加和删除数组元素

直接给一个新索引值复制

迭代数组

for/of循环、forEach()方法,老式for循环

  1. //把数组长度保存到局部变量中
  2. for(let i = 0,len = letters.length;i < len;i++) {
  3. //循环体不变
  4. }
  5. //从后向前迭代数组
  6. for(let i = letters.length-1;i >= 0;i--) {
  7. //循环体不变
  8. }
  9. //如果元素中包含undefined
  10. for(let i = 0,i < a.length;i++) {
  11. if(a[i] === undefined) continue; //跳过未定义及不存在的元素
  12. //这里的循环体
  13. }

数组方法

forEach()方法迭代数组的每一个元素,并对每个元素都调用一次我们指定的函数。

map()方法把调用它的数组的每个元素分别传给我们指定的函数,返回这个函数的返回值构成的数组。

filter()方法返回一个数组,该数组包含调用它的数组的子数组。传给这个方法的函数应该是个断言函数,即返回true或false的函数。

  1. let a = [5,4,3,2,1];
  2. a.filter(x => x < 3) // => [2, 1], 小于3的值
  3. a.filter((x,i) => i%2 === 0) // => [5, 3, 1],隔一个选一个
  4. //同时,filter()会跳过稀疏数组中缺失的元素,它返回的数组始终是稠密的。
  5. //因此可以使用filter()方法清理掉稀疏数组中的空隙
  6. let dense = sparse.filter(() => true);
  7. //删除值为undefined和null的元素
  8. a = a.filter(x => x !== undefined && x !== null);

find()和findIndex()方法寻找断言函数返回真值的元素,这两个方法会在断言函数找到第一个元素时停止迭代。此时,find()返回匹配的元素,findIndex()返回匹配元素的索引,如果没有找到匹配的元素,则find()返回undefined,而findIndex()返回-1。

every()和some()方法是数组断言方法,即它们会对数组元素调用我们传入的断言函数,最后返回true或false。

  1. //every()方法且旨在断言函数对数组的所有元素都返回true时才返回true
  2. let a = [1,2,3,4,5]
  3. a.every(x => x < 10) //=> true: 所有值都小10
  4. a.every(x => x % 2 === 0) //=> false: 并非所有值都是偶数
  5. //some()方法只要数组元素中有一个让断言函数返回true它就返回true,
  6. //但必须数组的所有元素对断言函数都返回false才返回false
  7. let a = [1,2,3,4,5]
  8. a.some(x => x%2 === 0) //=> true,a包含偶数
  9. a.some(isNaN) //=> false,a没有非数值

reduce()和reduceRight()方法使用我们指定的函数归并数组元素,最终产生一个值。

  1. //reduce()接收两个参数。
  2. //第一个参数是执行归并操作的函数,这个归并函数的任务就是把两个值归并或组合为一个值。
  3. //第二个参数是可选的,是传给归并函数的初始值。
  4. let a = [1,2,3,4,5]
  5. a.reduce((x,y) => x+y,0) //=> 15;所有值之和
  6. a.reduce((x,y) => x*y,1) //=> 120;所有值之积
  7. a.reduce((x,y) => (x > y) ? x : y) //=> 5,最大值
  8. //reduceRight()与reduce()类似,只不过是从高索引向低索引(从右到左)处理数组。
  9. //计算2^(3^4)。求幂具有从右到左的优先级
  10. let a = [2, 3, 4];
  11. a.reduceRight((acc,val) => Math.pow(val,acc))

flat()和flatMap()打平数组

  1. //flat()方法用于创建并返回一个新数组,这个新数组包含与它调用flat()的数组相同的元素,
  2. //只不过其中任何本身也是数组的元素会被"打平"填充到返回的数值中。
  3. [1,[2, 3]].flat() //=> [1,2,3]
  4. [1,[2, [3]]].flat() //=> [1, 2, [3]]
  5. //只需给flat()传一个数值参数,即可打平更多层级
  6. let a = [1, [2, [3, [4]]]];
  7. a.flat(1) //=> [1, 2, [3, [4]]]
  8. a.flat(2) //=> [1, 2, 3, [4]]
  9. a.flat(3) //=> [1, 2, 3, 4]
  10. a.flat(4) //=> [1, 2, 3, 4]
  11. //flatMap()方法与map()方法相似,只不过返回的数组会自动被打平,就像传给了flat()一样。
  12. let phrases = ["hello world","the definitive guide"];
  13. let words = phrases.flatMap(phrase => purase.split(" "));
  14. words // => ["hello","world","the","definitive","guide"];

concat()方法创建并返回一个新数组

  1. let a = [1,2,3]
  2. a.concat(4,5) //=> [1,2,3,4,5]
  3. a.concat([4,5],[6,7]) //=> [1,2,3,4,5,6,7],数组被打平了
  4. a.concat(4, [5,[6,7]]) //=> [1,2,3,4,5,[6,7]],但不会打平嵌套的数组
  5. a //=> [1,2,3],原始数组没有改变
  6. 注意,concat()会创建调用它的数组的副本,这样操作代价有点大。

push()方法在数组末尾添加一个或多个元素

pop()方法删除数组最后一个元素并返回该元素,同时导致数组长度减1

shift()方法删除并返回数组的第一个元素,让数组长度减1并将所有元素移动到低一位

unshift()方法在数组开头添加一个或多个元素,已有元素的索引会相应向更高索引移动,并返回数组的新长度

slice()方法接收两个参数,分别是用于指定要返回切片的起止位置。

如果只指定一个参数,返回的数组将包含从该七点开始直到数组末尾的所有元素。如果任何一个参数是负值,则这个值对于数组长度指定数组元素。比如,参数-1指定数组的最后一个元素,参数-2指定倒数第二个元素。
注意,slice()不会修改调用它的数组。

  1. let a = [1,2,3,4,5];
  2. a.slice(0,3); // 返回[1,2,3,4]
  3. a.slice(3); // 返回[3,4]
  4. a.slice(1,-1); // 返回[2,3,4]
  5. a.slice(-3,-2); // 返回[3]

splice()是一个可以插入、删除或替换数组元素的通用方法

第一个参数指定插入或删除操作的起点位置。
第二个参数指定要从数组中删除(切割出来)的元素个数。
splice()的前两个参数指定要删除哪些元素。这两个参数后面还可以跟任意多个参数,表示要在第一个参数指定的位置插入到数组的元素。
如果省略第二个参数,从起点元素开始的所有数组元素都将被删除。
splice()返回被删除元素的数组,如果没有删除元素则返回空数组。

  1. let a = [1,2,3,4,5,6,7,8];
  2. a.splice(4) //=> [5,6,7,8], a现在是[1,2,3,4]
  3. a.splice(1,2) //=> [2,3], a现在是[1,4]
  4. a,splice(1,1) //=> [4], a现在是[1]
  5. let a = [1,2,3,4,5]
  6. a.splice(2,0,"a","b") //=> []; a现在是[1,2,"a","b",3,4,5]
  7. a.splice(2,2,[1,2],3) //=> ["a","b"]; a现在是[1,2,[1,2],3,3,4,5]

fill()方法将数组的元素或切片设置为指定的值,会修改调用它的数组,也返回修改后的数组

第一个参数是要把数组元素设置成的值。
第二个参数是可选的,指定起始索引,如果省略则从索引0开始填充。
第三个参数是可选的,指定终止索引,到这个索引为止(但不包含)的数组元素会被填充,也可以传入负值相对于数组末尾指定索引。若省略,则从起始索引开始一直填充到数组末尾。

  1. let a = new Array(5);
  2. a.fill(0) //=> [0,0,0,0,0], 用0填充数组
  3. a.fill(9, 1) //=> [0,9,9,9,9], 从索引1开始填充
  4. a.fill(8, 2, -1) //=> [0,9,8,8,9], 在索引2、3填充8

copyWithin()方法把数组切片复制到数组中的新位置。它会就地修改数组并返回修改后的数值,但不会改变数组的长度。

第一个参数指定要把第一个元素复制到的目的索引。
第二个参数指定要复制的第一个元素的索引。如果省略第二个参数,则默认值为0。
第三个参数指定要复制的元素的的切片的终止索引。如果省略则使用数组的长度。也可以传入负值相对于数组末尾指定索引。

  1. let a = [1,2,3,4,5]
  2. a.copyWithin(1) //=> [1,1,2,3,4]: 把数组元素复制到索引1及以后
  3. a.copyWithin(2,3,5) //=> [1,1,3,4,4]: 把最后两个元素复制到索引2
  4. a.copyWithin(0,-2) //=> [4,4,3,4,4]: 负偏移量也可以

indexOf()和lastIndexOf()从数组中搜索指定的值并返回第一个找到的元素的索引,如果没有找到则返回-1。

indexOf()从前都后搜索数组,而lastIndexOf()从后向前搜索数组
indexOf()和lastIndexOf()都接收第二个可选的参数,指定从哪个位置开始搜索,可省略,第二个参数可以是负值,相对于数组末尾偏移。比如,-1指定数组的最后一个元素。

includes()方法接收一个参数,如果数组包含该值则返回true,否则返回true。

sort()对数组元素就地排序并返回排序后的数组。

  1. //在不传参调用时,sort()按字母顺序对数组元素排序
  2. //如果数组包含未定义的元素,它们会被排到数组末尾
  3. let a = ["banana","cherry","apple"];
  4. a.sort(); //a == ["apple","banana","cherry"]
  5. //对数组元素执行非字母顺序的排序,需给sort()传一个比较函数作为参数。
  6. let a = [33, 4, 1111, 222];
  7. a.sort(); //a == [1111, 222, 33, 5] 字母顺序
  8. a.sort(function(a,b){ //传入一个比较函数
  9. return a-b; //取决顺序,返回<0、0或>0
  10. }); //a == [4, 33, 222, 111],数值顺序
  11. a.sort((a,b) => b-a); //a == [1111, 222, 33, 4],相反的数值顺序

reverse()方法反转数组元素的顺序,并返回反序的数组,会直接对已经存在的数组进行反序

join()方法把数组的所有元素转换为字符串,可以指定一个可选的字符串参数,如果不指定则默认是逗号

toString()方法,逻辑与没有参数的join()方法一样。

Array.isArray() 传入一个数组,确定未知值是不是数组

Array.from() 类数组转换

delete操作符删除数组元素

  1. let a = [1,2,3]
  2. delete a[2]; //现在索引2没有元素了
  3. 2 in a //=> false: 数组索引2没有定义
  4. a.length //=> 3: 删除元素不影响数组长度