本文首发于 前端基础:ES6+ 常用语法
声明
-
let
let a = 1 let b = 2, c = 3 console.log(a, b, c) // 1 2 3
let
用于声明一个块级作用域的本地变量,不允许重复声明且不会造成变量提升。let
的出现解决了var
造成变量提升、覆盖和泄露等问题。 -
const
const a = 1 console.log(a) // 1
const
用于声明常量,即不允许重新赋值(修改变量指向的内存地址),也不允许重复声明。不会造成变量提升。有关
var
、let
与const
的详细介绍,可以参考 JS:var、let 与 const 总结
解构
-
解构对象
const tom = { name: 'Tom', age: 18, city: 'Beijing', } // 基础用法 const { name, age } = tom console.log(name, age) // Tom 18 // 属性重命名 const { name: myName } = tom console.log(myName) // Tom // 设置默认值 const { city, country = 'China' } = tom console.log(city, country) // Beijing China
-
解构数组
const arr = [1, 2, 3] const [a, b, c] = arr console.log(a, b, c) // 1 2 3
如果数组的长度不一致,可以使用
...
来解构,只保留长度一致的部分。const arr = [1, 2, 3] const [a, ...rest] = arr console.log(a, rest) // 1 [2, 3] const [a, b, c, ...rest] = arr console.log(a, b, c, rest) // 1 2 3 []
-
解构函数参数
function foo({ name, age }) { console.log(name, age) } foo({ name: 'Tom', age: 18 }) // Tom 18 function bar([a, b, c]) { console.log(a, b, c) } bar([1, 2, 3]) // 1 2 3
-
解构字符串
const str = 'hello' const [a, b, c, d] = str console.log(a, b, c, d) // h e l l
字符串
-
模板字符串
const name = 'Tom' const age = 18 const str = `Hello, I'm ${name}, ${age} years old.` console.log(str) // Hello, I'm Tom, 18 years old.
模板字符串的出现,是字符串的一个重要特性,它可以提供更加灵活的字符串拼接方式。
-
startsWith()
const str = 'hello' console.log(str.startsWith('h')) // true console.log(str.startsWith('e')) // false
startsWith()
方法用于判断字符串是否以指定的字符串开头,如果是,则返回 true,否则返回 false。 -
endsWith()
const str = 'hello' console.log(str.endsWith('o')) // true console.log(str.endsWith('e')) // false
endsWith()
方法用于判断字符串是否以指定的字符串结尾,如果是,则返回 true,否则返回 false。 -
includes()
const str = 'hello' console.log(str.includes('h')) // true console.log(str.includes('e')) // true console.log(str.includes('x')) // false
includes()
方法用于判断字符串是否包含指定的字符串,如果是,则返回 true,否则返回 false。 -
repeat()
const str = 'ha~' console.log(str.repeat(3)) // ha~ha~ha~
repeat(n)
方法用于将一个字符串重复 n 次,如果 n 是小于 1 的数值,则返回一个空字符串。
数字
-
Math.sign()
const a = -3 const b = 0 const c = 3 console.log(Math.sign(a)) // -1 console.log(Math.sign(b)) // 0 console.log(Math.sign(c)) // 1
Math.sign()
方法用于获取一个数的符号,如果是正数,则返回 1,如果是负数,则返回 -1,如果是 0,则返回 0。
数组
-
Array.from()
const arrayLike = { 0: 'a', 1: 'b', 2: 'c', length: 3, } console.log(Array.from(arrayLike)) // ['a', 'b', 'c'] const str = 'hello' console.log(Array.from(str)) // ['h', 'e', 'l', 'l', 'o'] const mySet = new Set([1, 2, 3]) console.log(Array.from(mySet)) // [1, 2, 3] const myMap = new Map([ ['a', 1], ['b', 2], ['c', 3], ]) console.log(Array.from(myMap)) // [['a', 1], ['b', 2], ['c', 3]]
Array.from()
方法用于将一个类数组(伪数组)或者可迭代对象转换成一个真正的数组。 -
Array.of()
console.log(Array.of(1, 2, 3)) // [1, 2, 3]
Array.of()
方法用于将一组值,转换成一个数组。 -
Array.prototype.find()
const studentList = [ { id: 1, name: 'Tom', age: 12, }, { id: 2, name: 'Jerry', age: 13, }, { id: 3, name: 'Bob', age: 11, }, ] const student = studentList.find(item => item.id === 2) console.log(student) // { id: 2, name: 'Jerry', age: 13 }
find()
方法用于返回数组中满足提供的测试函数的第一个元素的值。 -
Array.prototype.findIndex()
const studentList = [ { id: 1, name: 'Tom', age: 12, }, { id: 2, name: 'Jerry', age: 13, }, { id: 3, name: 'Bob', age: 11, }, ] const index = studentList.findIndex(item => item.id === 2) console.log(index) // 1
findIndex()
方法用于返回数组中满足提供的测试函数的第一个元素的索引。 -
Array.prototype.fill()
const arr = [1, 2, 3, 4, 5] console.log(arr.fill(0)) // [0, 0, 0, 0, 0] console.log(arr.fill(0, 1)) // [1, 0, 0, 0, 0] console.log(arr.fill(0, 1, 3)) // [1, 2, 0, 0, 0]
fill()
方法用于使用一个固定值,填充一个数组。 -
Array.prototype.copyWithin()
const arr = [1, 2, 3, 4, 5] console.log(arr.copyWithin(0, 3)) // [4, 5, 3, 4, 5] console.log(arr.copyWithin(0, 3, 4)) // [4, 2, 3, 4, 5]
copyWithin()
方法用于将一个数组的元素复制到另一个位置,然后返回这个数组。 -
Array.prototype.entries()
const arr = [1, 2, 3, 4, 5] for (const [index, value] of arr.entries()) { console.log(index, value) } // 0 1 // 1 2 // 2 3 // 3 4 // 4 5
entries()
方法返回一个新的 Array Iterator 对象,该对象包含数组中每个索引的键值对。
对象
-
Object.assign()
const obj1 = { a: 1, b: 2, c: 3, } const obj2 = { b: 4, c: 5, d: 6, } const obj3 = Object.assign(obj1, obj2) console.log(obj3) // { a: 1, b: 4, c: 5, d: 6 }
Object.assign()
方法用于将所有可枚举属性的值从一个或多个源对象复制到目标对象。它将返回目标对象。 -
简洁表示法
const str = 'hello' const arr = [1, 2, 3] const obj = { str, arr, a: 1, } console.log(obj) // { str: 'hello', arr: [1, 2, 3], a: 1 }
函数
-
箭头函数
const foo = () => { console.log('foo') } foo() // foo
箭头函数表达式的语法比函数表达式更简洁,没有自己的 this,arguments,super 或 new.target。箭头函数表达式更适用于那些本来需要匿名函数的地方。
箭头函数不能用作构造函数。
-
参数默认值
function foo(x = 1, y = 2) { console.log(x, y) } foo() // 1 2 foo(2) // 2 2 foo(2, 3) // 2 3 foo(undefined, 3) // 1 3
-
参数展开
function foo(x, y, ...rest) { console.log(x, y, rest) } foo(1, 2, 3, 4, 5) // 1 2 [3, 4, 5]
...
可以放在任何参数的最后一位,用于获取函数调用时所有未被消费的参数。
数据结构
-
Set
const set = new Set([1, 2, 3, 4, 5]) console.log(set.has(1)) // true console.log(set.has(6)) // false console.log(set.size) // 5
Set
数据结构是一个无序的集合,每个元素都唯一。 -
Map
const myMap = new Map([['name', 'Tom']]) console.log(myMap.get('name')) // Tom myMap.set('age', 25) // 添加键值对 console.log(myMap.has('age')) // true myMap.delete('age') // 删除键值对 console.log(myMap.has('age')) // false myMap.set(NaN, 'not a number') // Map 的键可以是任意值,包括函数、对象或任意基本类型 console.log(myMap.get(NaN)) // "not a number" console.log(myMap.size) // 3 // Map 可以直接被迭代 myMap.forEach((value, key) => { console.log(key + ' = ' + value) // name = Tom NaN = not a number })
Map
数据结构是键值对集合,一个 Map 的键可以是任意值,包括函数、对象或任意基本类型。Map 可以直接被迭代。
其它
-
扩展运算符(展开语法)
const arr = [1, 2] console.log(...arr) // 1 2 const str = 'hello' console.log(...str) // h e l l o
-
for in
const obj = { a: 1, b: 2 } for (let key in obj) { console.log(key) // a b }
for in
可以遍历对象的键名。 -
for of
const arr = [1, 2] for (let item of arr) { console.log(item) // 1 2 }
for of
可以遍历数组的成员。 -
class
class Student { constructor(name) { this.name = name } sayName() { console.log(`My name is ${this.name}`) } } const student = new Student('Bob') student.sayName() // My name is Bob
class
关键字用于创建一个类。可以理解为 ES5 的构造函数的语法糖。关于构造函数与
class
,可以参考 JS:构造函数总结。 -
Promise
const asyncFunc = new Promise((resolve, rejcet) => { Math.random() > 0.5 ? resolve('fulfilled') : rejcet('rejected') }) asyncFunc .then(data => { console.log(data) // fulfilled }) .catch(err => { console.log(err) // rejected }) .finally(() => { console.log('finally') })
Promise
是 ES6 新增的一种异步操作解决方案。Promise
对象的状态可以有 3 个:pending
、fulfilled
和rejected
。当状态发生改变时,会触发相应的回调函数。 -
async/await
async function hello() { return await Promise.resolve('Hello') } hello().then(console.log) // Hello
async/await
是 ES2017 中新增的异步解决方案。简单来说,它们是基于Promise
的语法糖,使异步代码更易于编写和阅读。async
函数返回一个Promise
对象,await
关键字只能用在async
函数中,不能用在其他函数中。关于更多
async/await
的介绍,可以参考 JS:async/await 总结。 -
Proxy
const cat = { name: 'Tom', } const myCat = new Proxy(cat, { get(target, property) { console.log(`我的 ${property} 被读取了`) return property in target ? target[property] : undefined }, set(target, property, value) { console.log(`我的 ${property} 被设置成了 ${value}`) target[property] = value return true }, }) myCat.name // expected output: 我被读取了:name myCat.name = 'Kitty' // expected output: 我的 name 被设置成了 Kitty
Proxy
可以代理任何对象,包括数组。Proxy
可以直接监听整个对象而非属性,比Object.defineProperty()
更加简洁,更加高效,更加安全。Proxy
返回的是一个新对象,我们可以只操作新的对象达到目的。 -
Reflect
const cat = { name: 'Tom', } Reflect.set(cat, 'age', 5) console.log(Reflect.get(cat, 'name')) // Tom console.log(cat.age) // 5 console.log(Reflect.has(cat, 'name')) // true console.log(Reflect.ownKeys(cat)) // ['name', 'age']
Reflect
是一个对象,而非构造函数。主要用于访问和修改对象的属性。Reflect
和Object
看似雷同,但存在许多差异,具体可以参考 比较 Reflect 和 Object 方法。 -
Symbol
const mySymbol = Symbol() console.log(typeof mySymbol) // "symbol" console.log(Symbol() === Symbol()) // false
Symbol
是 ES6 新增的一种基本数据类型。Symbol
表示一个独一无二的值。 -
Generator
function* helloWorldGenerator() { yield 'hello' yield 'world' return 'ending' } const hw = helloWorldGenerator() console.log(hw.next()) // { value: 'hello', done: false } console.log(hw.next()) // { value: 'world', done: false } console.log(hw.next()) // { value: 'ending', done: true }
Generator
是 ES6 新增的一种异步编程模型。Generator
函数是一个状态机,遇到yield
就会暂停执行,并返回一个{ value, done }
的对象,value
属性表示返回的值,done
属性表示是否完成。 -
Module
// math.js export function add(x, y) { return x + y }
// app.js import { add } from './math' console.log(add(1, 2)) // 3
Module
是 ES6 新增的模块化语法,可以将代码拆分成多个文件,并且可以通过import
和export
来导入和导出。
使用 Babel 将 ES6+ 转换为 ES5
-
为什么要将 ES6+ 转换为 ES5?
因为 ES6+ 是 JavaScript 的新语法,我们虽然可以在开发时使用,但是直接运行在浏览器中的话,许多语法浏览器是不支持的,所以要将 ES6+ 转换为 ES5。
-
为什么要使用 Babel?
Babel 是一个 JavaScript 编译器,可以将 ES6+ 转换为 ES5。
-
安装 Babel
npm i @babel/core babel-loader @babel/preset-env -D
@babel/core
是 Babel 的核心包。babel-loader
是 Webpack 的 loader,用于在 Webpack 打包时调用 Babel,从而将 ES6+ 转换为 ES5。@babel/preset-env
提供了一些预置的 Babel 配置,这是一个智能预设,只要安装这一个 preset,就会根据你设置的目标浏览器,自动将代码中的新特性转换成目标浏览器支持的代码。-D
表示安装到package.json
中的开发依赖。 -
在 Webpack 中使用 Babel
module.exports = { module: { rules: [ { test: /\.js$/, exclude: /node_modules/, use: { loader: 'babel-loader', options: { presets: ['@babel/preset-env'], }, }, }, ], }, }
参考资料:
网友评论