1. 变量声明
let 和 const
// let - 块级作用域,可重新赋值
let name = 'John'
name = 'Jane' // 可以
// const - 块级作用域,不可重新赋值
const age = 25
// age = 26 // 报错
// 块级作用域
{
let x = 1
const y = 2
}
// console.log(x) // 报错,x 不存在2. 模板字符串
const name = 'World'
const greeting = `Hello, ${name}!`
// 多行字符串
const html = `
<div>
<h1>${title}</h1>
<p>${content}</p>
</div>
`
// 标签模板
function highlight(strings, ...values) {
return strings.reduce((result, string, i) => {
return result + string + (values[i] ? `<mark>${values[i]}</mark>` : '')
}, '')
}3. 箭头函数
// 基本语法
const add = (a, b) => a + b
const square = x => x * x
const greet = () => 'Hello'
// this 绑定的区别
function Timer() {
this.seconds = 0
// 箭头函数继承外层 this
setInterval(() => {
this.seconds++
}, 1000)
}
// 不能作为构造函数
const Person = (name) => {
this.name = name
}
// new Person() // 报错4. 解构赋值
数组解构
const [a, b, c] = [1, 2, 3]
const [first, , third] = [1, 2, 3] // 跳过元素
const [x, y, ...rest] = [1, 2, 3, 4, 5] // rest: [3, 4, 5]
// 默认值
const [name = 'Anonymous'] = []对象解构
const { name, age } = { name: 'John', age: 25, city: 'NYC' }
// 重命名
const { name: userName, age: userAge } = user
// 嵌套解构
const { address: { street, city } } = user
// 函数参数解构
function greet({ name, age = 18 }) {
return `Hello ${name}, you are ${age}`
}5. 默认参数
function greet(name = 'World', punctuation = '!') {
return `Hello, ${name}${punctuation}`
}
// 可以使用表达式
function createUser(name, id = Date.now()) {
return { name, id }
}
// 参数可以引用前面的参数
function multiply(a, b = a) {
return a * b
}6. 展开运算符(Spread)
// 数组展开
const arr1 = [1, 2, 3]
const arr2 = [...arr1, 4, 5] // [1, 2, 3, 4, 5]
// 对象展开
const obj1 = { a: 1, b: 2 }
const obj2 = { ...obj1, c: 3 } // { a: 1, b: 2, c: 3 }
// 函数调用
function sum(a, b, c) {
return a + b + c
}
const numbers = [1, 2, 3]
sum(...numbers) // 等同于 sum(1, 2, 3)
// 复制数组/对象
const newArr = [...oldArr]
const newObj = { ...oldObj }7. 剩余参数(Rest)
function sum(...numbers) {
return numbers.reduce((total, num) => total + num, 0)
}
sum(1, 2, 3, 4) // 10
// 与普通参数结合
function greet(greeting, ...names) {
return `${greeting} ${names.join(', ')}`
}
greet('Hello', 'John', 'Jane', 'Bob')8. 类(Class)
class Person {
constructor(name, age) {
this.name = name
this.age = age
}
// 方法
greet() {
return `Hello, I'm ${this.name}`
}
// 静态方法
static species() {
return 'Homo sapiens'
}
// getter/setter
get info() {
return `${this.name} (${this.age})`
}
set age(value) {
if (value < 0) throw new Error('Age cannot be negative')
this._age = value
}
}
// 继承
class Student extends Person {
constructor(name, age, grade) {
super(name, age) // 调用父类构造函数
this.grade = grade
}
study() {
return `${this.name} is studying`
}
}9. 模块系统
// 导出 (export)
export const PI = 3.14159
export function add(a, b) {
return a + b
}
export default class Calculator {
// ...
}
// 导入 (import)
import Calculator, { PI, add } from './calculator.js'
import * as math from './math.js'
import { add as sum } from './calculator.js'
// 动态导入
import('./module.js').then(module => {
// 使用模块
})10. Promise
// 创建 Promise
const promise = new Promise((resolve, reject) => {
setTimeout(() => {
if (Math.random() > 0.5) {
resolve('Success!')
} else {
reject(new Error('Failed!'))
}
}, 1000)
})
// 使用 Promise
promise
.then(result => console.log(result))
.catch(error => console.error(error))
.finally(() => console.log('Done'))
// Promise 静态方法
Promise.all([promise1, promise2, promise3])
Promise.race([promise1, promise2])
Promise.resolve(value)
Promise.reject(error)11. Symbol
// 创建 Symbol
const sym1 = Symbol()
const sym2 = Symbol('description')
const sym3 = Symbol.for('global-symbol')
// 作为对象属性
const obj = {
[sym1]: 'value1',
[Symbol.iterator]: function* () {
yield 1
yield 2
yield 3
}
}
// 内置 Symbol
Symbol.iterator // 迭代器
Symbol.hasInstance // instanceof
Symbol.toPrimitive // 类型转换12. 迭代器和生成器
迭代器
const iterable = {
[Symbol.iterator]() {
let step = 0
return {
next() {
if (step < 3) {
return { value: step++, done: false }
}
return { done: true }
}
}
}
}
for (const value of iterable) {
console.log(value) // 0, 1, 2
}生成器
function* numberGenerator() {
yield 1
yield 2
yield 3
return 'done'
}
const gen = numberGenerator()
console.log(gen.next()) // { value: 1, done: false }
console.log(gen.next()) // { value: 2, done: false }
// 无限序列
function* fibonacci() {
let [a, b] = [0, 1]
while (true) {
yield a
;[a, b] = [b, a + b]
}
}13. 新的数据结构
Set
const set = new Set([1, 2, 3, 3]) // {1, 2, 3}
set.add(4)
set.has(2) // true
set.delete(1)
set.size // 3
// 数组去重
const unique = [...new Set(array)]Map
const map = new Map()
map.set('key1', 'value1')
map.set(42, 'number key')
map.set({}, 'object key')
map.get('key1') // 'value1'
map.has(42) // true
map.size // 3
// 遍历
for (const [key, value] of map) {
console.log(key, value)
}WeakSet 和 WeakMap
// WeakSet - 只能存储对象,弱引用
const weakSet = new WeakSet()
const obj = {}
weakSet.add(obj)
// WeakMap - 键只能是对象,弱引用
const weakMap = new WeakMap()
weakMap.set(obj, 'some value')14. 增强的对象字面量
const name = 'John'
const age = 25
// 属性简写
const person = { name, age }
// 方法简写
const obj = {
greet() {
return 'Hello'
},
// 计算属性名
[name + '_info']: 'some info',
// 可以使用表达式
['prop_' + (() => 42)()]: true
}15. 新的数组方法
// Array.from - 类数组转数组
Array.from('hello') // ['h', 'e', 'l', 'l', 'o']
Array.from([1, 2, 3], x => x * 2) // [2, 4, 6]
// Array.of - 创建数组
Array.of(1, 2, 3) // [1, 2, 3]
// find/findIndex
[1, 2, 3, 4].find(x => x > 2) // 3
[1, 2, 3, 4].findIndex(x => x > 2) // 2
// fill
new Array(3).fill(0) // [0, 0, 0]
// includes
[1, 2, 3].includes(2) // true16. 新的字符串方法
// includes, startsWith, endsWith
'hello world'.includes('world') // true
'hello world'.startsWith('hello') // true
'hello world'.endsWith('world') // true
// repeat
'abc'.repeat(3) // 'abcabcabc'
// padStart, padEnd
'5'.padStart(3, '0') // '005'
'5'.padEnd(3, '0') // '500'面试重点
在面试中,重点关注这些内容:
- let/const - 块级作用域,暂时性死区
- 箭头函数 - this 绑定,不能作为构造函数
- 解构赋值 - 提高代码简洁性
- Promise - 异步编程的重要改进
- Class - 面向对象编程的语法糖
- 模块系统 - 现代 JavaScript 开发的基础
- 模板字符串 - 字符串处理的改进
这些特性大大提升了 JavaScript 的开发体验和代码质量!