JavaScript经历了不同标本的迭代,在不断完善中会添加不同的新特性来解决前一个阶段的瑕疵,让我们开发更加便捷与写法更加简洁!
1、箭头函数:
箭头函数相比传统的函数语法,具有更简洁的语法、没有自己的this值、不会绑定arguments关键字,并且在没有new关键字时不会生成this上下文。
- 传统的函数定义
function add(x, y) { return x + y; }
- 箭头函数的定义
const add = (x, y) => x + y;
2、解构赋值
允许把数组或者对象的属性,直接赋值给其他变量。
- 数组的解构赋值
let [a, b, c] = [1, 2, 3];
- 对象的解构赋值
let { foo, bar } = { foo: 'aaa', bar: 'bbb' };
3、默认、剩余、展开:
- 默认参数
function f(x = 10) { ... }
- 剩余参数
function f(...args) { ... }
- 展开运算符
let arr = [...args]
4、模板字符串
使用反引号(``)创建的字符串可以跨越多行,并可以嵌入表达式。
const name = 'Jack'; const message = `My name is ${name}.`;
5、import模块
引入了 import 和 export 关键字,用来定义模块的导入和导出。模块可以帮助我们更好地组织代码,避免命名冲突和代码重复。
如果想要导入模块的默认导出,可以使用import defaultExportedValue from 'module’语法。如果想要同时导入多个变量或函数,可以使用import { variable1, variable2 } from 'module’语法。
//make.js //定义函数方法 function makeStyleGuide() {} //导出 export default makeStyleGuide;
//index.js import makeStyleGuide from 'make.js';
如果想要导入模块的默认导出,可以使用语法。
import defaultExportedValue from 'module'
如果想要同时导入多个变量或函数,可以使用语法。
import { variable1, variable2 } from 'module'
6、Array.prototype.includes()
用来判断一个数组是否包含一个指定的值,根据情况,如果包含则返回true,否则返回false。
let arr = ['react', 'angular', 'vue']; console.log(arr.includes('react')); // true
使用 includes()查找字符串是区分大小写的。
使用 includes()只能判断简单类型的数据,对象类型的数组,二维数组,这些是无法判断的。
使用 includes()能识别NaN
如果只想知道某个值是否在数组中存在,而并不关心它的索引位置,建议使用includes(),如果想获取一个值在数组中的位置,那么使用indexOf方法。
7、Object.values()
方法返回一个数组,成员是参数对象自身的(不含继承的)所有可遍历(enumerable)属性的键值。
const obj = { name: "Lucy", age: 18 } console.log(Object.values(obj)); // ['Lucy', 18,]
8、String.prototype.padStart和String.prototype.padEnd
padStart:用另一个字符串填充当前字符串,在原字符串开头填充指定的填充字符串直到目标长度所形成的新字符串
padEnd:用另一个字符串填充当前字符串,在原字符串结尾填充指定的填充字符串直到目标长度所形成的新字符串
语法
str.padStart(targetLength , padString)
- targetLength
当前字符串需要填充到的目标长度。如果这个数值小于当前字符串的长度,则返回当前字符串本身。 - padString 可选
填充字符串。如果字符串太长,使填充后的字符串长度超过了目标长度,则只保留最左侧的部分,其他部分会被截断。此参数的默认值为 " "
const str = "ABC"; console.log(str.padStart(10,'a')) //aaaaaaaABC console.log(str.padEnd(10, '123')) //ABC1231231
应用场景
- 日期格式化:yyyy-mm-dd的格式
const now = new Date(); const year = now.getFullYear(); const mounth = (now.getMonth() + 1).toString().padStart(2, '0') const day = (now.getDate()).toString().padStart(2, '0' console.log(`${year}-${mounth}-${day}`); //2023-11-02
- 信息脱敏:(手机号,银行卡号等)
const tel = '13245678901'; tel.slice(-4).padStart(tel.length, '*') // *******8901
9、可选链操作符
(?.)允许读取位于连接对象链深处的属性的值,而不必明确验证链中的每个引用都是否有效。?. 操作符的功能类似于.链式操作符,不同之处在于,在引用为 null 或 undefined 时不会报错,该链路表达式返回值为 undefined。与函数调用一起使用时,如果给定的函数不存在,则返回 undefined。
当尝试访问可能不存在的对象属性时,可选链操作符将会使表达式更短、更简明。在探索一个对象的内容时,如果不能确定哪些属性必定存在,可选链操作符也是很有帮助的。
- 传统的写法
const user = res && res.data && res.data.user;
- 可选链写法
const user = res?.data?.user;
- 可选链有以下三种形式:
a?.[x] // 等同于 a == null ? undefined : a[x] a?.b() // 等同于 a == null ? undefined : a.b() a?.() // 等同于 a == null ? undefined : a()
10、空值合并运算符 ‘??’
空值合并运算符(??)是一个逻辑运算符,当左侧的操作数为 null 或者 undefined 时,返回其右侧操作数,否则返回左侧操作数。与逻辑或运算符(||)不同,逻辑或运算符会在左侧操作数为假值时返回右侧操作数。也就是说,如果使用 || 来为某些变量设置默认值,可能会遇到意料之外的行为。比如为假值(例如,‘’ 或 0)时。
语法
a ?? b 的结果是:
- 如果 a 是已定义的,则结果为 a,
- 如果 a 不是已定义的,则结果为 b。
如果第一个参数不是 null/undefined,则 ?? 返回第一个参数。否则,返回第二个参数。
注意点:不可以和逻辑与&& 或逻辑或 || 一起使用
- 以前的写法
if(value !== null && value !== undefined && value !== ''){ }
- 现在的写法
if((value??'') !== ''){ }
优先级
?? 运算符的优先级与 || 相同,它们的的优先级都为 4
这意味着,就像 || 一样,空值合并运算符在 = 和 ? 运算前计算,但在大多数其他运算(例如 + 和 *)之后计算。
- 正确的写法
let height = null; let width = null; // 重要:使用括号 let area = (height ?? 100) * (width ?? 50); console.log(area); // 5000
- 错误的写法
let height = null; let width = null; // 没有括号 let area = height ?? 100 * width ?? 50; // 将这样计算 let area = height ?? (100 * width) ?? 50;
与 || 比较
|| 无法区分 false、0、空字符串 “” 和 null/undefined。它们都一样 —— 假值(falsy values)。如果其中任何一个是 || 的第一个参数,那么我们将得到第二个参数作为结果。
let height = 0; console.log(height || 100); // 100 console.log(height ?? 100); // 0
- height || 100 首先会检查 height 是否为一个假值,它是 0,确实是假值。所以,|| 运算的结果为第二个参数,100。
- height ?? 100 首先会检查 height 是否为 null/undefined,发现它不是。所以,结果为 height 的原始值,0。
实际上,高度 0 通常是一个有效值,它不应该被替换为默认值。所以 ?? 运算得到的是正确的结果。
11、String.prototype.replaceAll()
返回一个新字符串,字符串中所有满足 pattern 的部分都会被 replacement 替换掉。原字符串保持不变。
语法
String.prototype.replaceAll(pattern,replacement)
- pattern
可以是一个字符串或 RegExp;使用正则表达式搜索值时,必须是全局的。 - replacement
可以是一个字符串或一个在每次被匹配被调用的函数。
const str = "student is a real student"; const newStr = str.replaceAll('student', "hahaha"); console.log(newStr); //hahaha is a real hahaha
const str = "student is a real student"; const newStr = str.replaceAll(/student/g, "hahaha"); console.log(newStr); //hahaha is a real hahaha