前端必须要掌握的 ES6 语法总结

let 与 const

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 用于声明常量,即不允许重新赋值(修改变量指向的内存地址)和重复声明。const 也不会造成变量提升。

有关 varletconst 的详细介绍,可以参考 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] = str

console.log(a, b, c) // 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()

startsWith() 方法用于判断字符串是否以指定的字符串开头,如果是,返回 true,否则返回 false。

const str = "hello"

console.log(str.startsWith("h")) // true
console.log(str.startsWith("e")) // false

endsWith()

startsWith() 的兄弟,用于判断字符串是否以指定的字符串结尾,如果是,返回 true,否则返回 false。

const str = "hello"

console.log(str.endsWith("o")) // true
console.log(str.endsWith("e")) // false

includes()

用于判断字符串是否包含指定的字符串,如果是,返回 true,否则返回 false。

const str = "hello"

console.log(str.includes("h")) // true
console.log(str.includes("e")) // true
console.log(str.includes("x")) // false

repeat()

用于将一个字符串重复 n 次,如果 n 是小于 1 的数值,则返回一个空字符串。

const str = "ha~"

console.log(str.repeat(3)) // ha~ha~ha~

数字相关

Math.sign()

用于获取一个数的符号,如果是正数,则返回 1,如果是负数,则返回 -1,如果是 0,则返回 0。

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

数组相关

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']

将 Set 转换为数组

const mySet = new Set([1, 2, 3])

console.log(Array.from(mySet)) // [1, 2, 3]

将 Map 转换为数组

const myMap = new Map([
  ["a", 1],
  ["b", 2],
  ["c", 3],
])

console.log(Array.from(myMap)) // [['a', 1], ['b', 2], ['c', 3]]

Array.of()

Array.of() 用于将一组值(用逗号隔开)转换成一个数组。

const arr = Array.of(1, 2, 3)

console.log(arr) // [1, 2, 3]

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.age === 13)

console.log(student) // { id: 2, name: 'Jerry', age: 13 }

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.age === 13)

console.log(index) // 1

fill()

fill() 方法用于用指定值填充数组。

const arr = [1, 1, 1, 1, 1]

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, 0, 0, 1, 1]

其中第一个参数就是指定值,第二个参数为起始索引,默认为 0,第三个参数为终止索引,默认为数组的长度,即填充到最后一位。

对象

Object.assign()

Object.assign() 用于将所有可枚举属性的值从一个或多个源对象复制(浅拷贝)到目标对象。

const groupA = {
  a: 1,
  b: 2,
  c: 3,
}

const groupB = {
  b: 4,
  c: 5,
  d: 6,
}

const all = Object.assign(groupA, groupB)

console.log(all) // { a: 1, b: 4, c: 5, d: 6 }

对于重复的元素,将以后面的(最新的)为准。

简洁表示法

ES6 允许在对象 {} 里面,直接写入变量或函数名,然后作为对象内的属性名。

const str = "hello"

const arr = [1, 2, 3]

const obj = {
  str, // 等同于 str: str
  arr, // 等同于 arr: arr
  num: 1,
}

console.log(obj) // { str: 'hello', arr: [1, 2, 3], num: 1 }

在函数内也可以:

function test() {
  let x = 1,
    y = 2
  return { x, y }
}

console.log(test()) // { x: 1, y: 2 }

函数

箭头函数

const foo = () => {
  console.log("foo")
}

foo() // foo

箭头函数的语法比函数表达式更简洁,并且没有自己的 this,arguments,super 或 new.target。很适用于需要匿名函数的地方。

const arr = [1, 2, 3, 4, 5]

const bigger = arr.filter(item => item >= 3)

console.log(bigger) // [ 3, 4, 5 ]

参数默认值

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

Map 和对象 {} 类似,都是一些键值对的集合。但是更加灵活。

const map = new Map()

map.set("a", 1)

console.log(map) // Map(1) { 'a' => 1 }

Map 的键可以是任意值,甚至可以是函数、对象

function b() {}

map.set(b, 2)

console.log(map) // Map(2) { 'a' => 1, [Function: b] => 2 }

Map 可以直接被迭代

map.forEach((value, key) => {
  console.log(key + " = " + value)
})

// 输出
// a = 1
// function b() {} = 2

Map 的键值对个数可以通过 size 获取

console.log(map.size) // 2

通用

扩展运算符(展开语法)

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 个:pendingfulfilledrejected。当状态发生改变时,会触发相应的回调函数。

关于更多 Promise 的介绍,可以参考:JS:手写实现 Promise

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

Proxy 用于创建一个对象的代理,从而实现基本操作的拦截和自定义(如属性查找、赋值、枚举、函数调用等)。可以代理任何对象,包括数组。可以直接监听整个对象而非属性,比 Object.defineProperty() 更加简洁,更加高效,更加安全。

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

Reflect

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']

ReflectObject 看似雷同,但存在许多差异,具体可以参考 比较 Reflect 和 Object 方法

Symbol

const mySymbol = Symbol()

console.log(typeof mySymbol) // "symbol"

console.log(Symbol() === Symbol()) // false

Symbol 是 ES6 新增的一种基本数据类型。Symbol 表示一个独一无二的值。

Generator

Generator 是 ES6 新增的一种异步编程模型。

Generator 函数是一个状态机,遇到 yield 就会暂停执行,并返回一个 { value, done } 的对象,value 属性表示返回的值,done 属性表示是否完成。

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 }

Module

Module 是 ES6 新增的模块化语法,可以将代码拆分成多个文件,并且可以通过 importexport 来导入和导出。

// math.js
export function add(x, y) {
  return x + y
}
// app.js
import { add } from "./math"

console.log(add(1, 2)) // 3

如何将 ES6+ 转换为 ES5

  • 为什么要将 ES6+ 转换为 ES5?

    因为 ES6+ 是 JavaScript 的新语法,我们虽然可以在开发时使用,但是直接运行在浏览器中的话,许多语法浏览器是不支持的,所以要将 ES6+ 转换为 ES5。

  • 安装 Babel

    Babel 是一个 JavaScript 编译器,可以将 ES6+ 转换为 ES5。

    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"],
              },
            },
          },
        ],
      },
    }
    

参考资料:

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,362评论 5 477
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,330评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,247评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,560评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,580评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,569评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,929评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,587评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,840评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,596评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,678评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,366评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,945评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,929评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,165评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 43,271评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,403评论 2 342

推荐阅读更多精彩内容

  • ES6 是什么 ECMAScript 2015 于2015年6月正式发布 可以使用babel语法转换器,支持低端浏...
    我是嘉炜阅读 188评论 0 2
  • ES6阮一峰老师的书已经出到第三版了,从中受益匪浅,第二版读了三遍,在项目中常用到的一些语法和方法做些总结 字符串...
    任雨丶阅读 15,548评论 0 11
  • ECMAScript 简介 它是一种由ECMA组织(前身为欧洲计算机制造商协会)制定和发布的脚本语言规范 而我们学...
    冬来Angus阅读 1,032评论 0 0
  • ES6阮一峰老师的书已经出到第三版了,从中受益匪浅,第二版读了三遍,在项目中常用到的一些语法和方法做些总结 字符串...
    程芬KELA阅读 502评论 0 0
  • ES6语法跟babel: 一、首先我们来解释一下什么是ES? ES的全称是ECMAScript。1996 11 ,...
    Mooya_阅读 975评论 0 0