# 高级数据结构和算法
# Map 和 Set 数据结构
在 JavaScript 中,Map 数据结构通常用于存储键值对,它可以使用任意类型作为键和值。Set 数据结构用于存储唯一值的集合。
// 创建 Map 对象 | |
const map = new Map(); | |
// 设置键值对 | |
map.set('name', 'Tom'); | |
map.set('age', 20); | |
// 获取键值对 | |
console.log(map.get('name')); // 'Tom' | |
console.log(map.get('age')); // 20 | |
// 创建 Set 对象 | |
const set = new Set(); | |
// 添加元素 | |
set.add(10); | |
set.add(20); | |
set.add(30); | |
// 删除元素 | |
set.delete(20); | |
// 判断元素是否存在 | |
console.log(set.has(10)); // true | |
console.log(set.has(20)); // false |
# 堆、栈和队列
堆和栈是常用的内存分配方式。栈是一种后进先出的数据结构,堆是一种动态分配的内存结构。队列是一种先进先出的数据结构,它通常用于缓存和并发编程中。
// 使用数组模拟堆 | |
const arr = [1, 2, 3, 4]; | |
arr.push(5); // 入堆 | |
console.log(arr.pop()); // 出堆 | |
// 使用数组模拟栈 | |
const stack = [1, 2, 3, 4]; | |
stack.push(5); // 入栈 | |
console.log(stack.pop()); // 出栈 | |
// 使用数组模拟队列 | |
const queue = [1, 2, 3, 4]; | |
queue.push(5); // 入队 | |
console.log(queue.shift()); // 出队 |
# 深度优先搜索和广度优先搜索
深度优先搜索(DFS)和广度优先搜索(BFS)是常用的遍历算法。DFS 通常用于解决深度问题,BFS 适用于宽度问题。
// 深度优先遍历 | |
function dfs(node) { | |
if (node == null) return; | |
console.log(node.value); | |
dfs(node.left); | |
dfs(node.right); | |
} | |
// 广度优先遍历 | |
function bfs(node) { | |
const queue = [node]; | |
while (queue.length) { | |
const curr = queue.shift(); | |
console.log(curr.value); | |
if (curr.left) queue.push(curr.left); | |
if (curr.right) queue.push(curr.right); | |
} | |
} |
# 常用算法
常用的算法有排序、搜索、查找等。
排序算法:快速排序使用分治思想,通过把数组分成较小的块来排序。
function quickSort(arr) { | |
if (arr.length < 2) { | |
return arr; | |
} | |
let pivot = arr[0]; | |
let left = []; | |
let right = []; | |
for (let i = 1; i < arr.length; i++) { | |
if (arr[i] < pivot) { | |
left.push(arr[i]); | |
} else { | |
right.push(arr[i]); | |
} | |
} | |
return [...quickSort(left), pivot, ...quickSort(right)]; | |
} | |
// 查找算法: | |
function binarySearch(arr, target) { | |
let left = 0; | |
let right = arr.length - 1; | |
while (left <= right) { | |
const mid = Math.floor((left + right) / 2); | |
if (arr[mid] === target) { | |
return mid; | |
} else if (arr[mid] < target) { | |
left = mid + 1; | |
} else { | |
right = mid - 1; | |
} | |
} | |
return -1; | |
} |
# 函数式编程
# 高阶函数和柯里化
高阶函数和柯里化是函数式编程中的常见概念,它们可以让我们创建更加抽象、灵活的函数。
// 高阶函数 | |
function higherOrderFunction(func) { | |
return function (num) { | |
return func(num); | |
}; | |
} | |
function double(num) { | |
return num * 2; | |
} | |
const doubleFunc = higherOrderFunction(double); | |
console.log(doubleFunc(10)); // 20 | |
// 柯里化 | |
function curry(func) { | |
return function curried(...args) { | |
if (args.length >= func.length) { | |
return func.apply(this, args); | |
} else { | |
return function (...args2) { | |
return curried.apply(this, [...args, ...args2]); | |
}; | |
} | |
}; | |
} | |
function sum(a, b, c) { | |
return a + b + c; | |
} | |
const curriedSum = curry(sum); | |
console.log(curriedSum(1)(2)(3)); // 6 |
# 闭包和作用域
闭包和作用域是 JavaScript 中比较常见的概念。闭包可以让我们维护函数内的状态,作用域则决定了变量的可见范围。
// 闭包 | |
function closure() { | |
let i = 0; | |
return function () { | |
return ++i; | |
}; | |
} | |
const func = closure(); | |
console.log(func()); // 1 | |
console.log(func()); // 2 | |
// 作用域 | |
let a = 10; | |
function foo() { | |
let a = 20; | |
console.log(a); // 20 | |
} | |
foo(); | |
console.log(a); // 10 |
# 函数式编程中的常见模式
函数式编程中有很多常见的模式,如 map、filter、reduce 等。
// map | |
const arr = [1, 2, 3]; | |
const mapArr = arr.map((item) => item * 2); | |
console.log(mapArr); // [2, 4, 6] | |
// filter | |
const filterArr = arr.filter((item) => item > 1); | |
console.log(filterArr); // [2, 3] | |
// reduce | |
const reduceArr = arr.reduce((sum, curr) => sum + curr, 0); | |
console.log(reduceArr); // 6 |
# 异步编程
# Promise 和 async/await
Promise 和 async/await 是常见的异步编程方式,它们可以让我们更好地处理异步编程中的问题。
// Promise | |
function promise() { | |
return new Promise((resolve, reject) => { | |
setTimeout(() => { | |
resolve('done'); | |
}, 1000); | |
}); | |
} | |
promise().then((result) => console.log(result)); // 'done' | |
// async/await | |
async function asyncFunc() { | |
const result = await promise(); | |
console.log(result); | |
} | |
asyncFunc(); // 'done' |
# 事件循环和 EventEmitter
事件循环和 EventEmitter 用于处理异步事件,它们可以让我们更好地处理事件流。
// 事件循环 | |
console.log('start'); | |
setTimeout(() => { | |
console.log('setTimeout'); | |
}, 0); | |
Promise.resolve().then(() => console.log('promise')); | |
console.log('end'); | |
// EventEmitter | |
const { EventEmitter } = require('events'); | |
const emitter = new EventEmitter(); | |
emitter.on('doSomething', (arg1, arg2) => { | |
console.log(`${arg1} ${arg2}`); | |
}); | |
emitter.emit('doSomething', 'Hello', 'World'); // 'Hello World' |
# Web Worker
Web Worker 可以让我们将长时间运行的任务移出主线程,以避免阻塞 UI。
// 主线程 | |
const worker = new Worker('worker.js'); | |
worker.onmessage = (event) => { | |
console.log(event.data); | |
}; | |
worker.postMessage('start'); | |
// worker.js | |
self.onmessage = (event) => { | |
const result = longCalculation(event.data); | |
self.postMessage(result); | |
}; |
# 面向对象编程
# 类和继承
JavaScript 中的类和继承与其他面向对象编程语言类似。
// 类 | |
class Animal { | |
constructor(name) { | |
this.name = name; | |
} | |
speak() { | |
console.log(`${this.name} makes a noise.`); | |
} | |
} | |
class Cat extends Animal { | |
constructor(name, breed) { | |
super(name); | |
this.breed = breed; | |
} | |
speak() { | |
console.log(`${this.name} meows.`); | |
} | |
get description() { | |
return `${this.name} is a ${this.breed} cat.`; | |
} | |
set nickname(nick) { | |
this.name = nick; | |
} | |
} | |
const cat = new Cat('Fluffy', 'Persian'); | |
cat.speak(); // 'Fluffy meows.' | |
console.log(cat.description); // 'Fluffy is a Persian cat.' | |
cat.nickname = 'Fuffy'; | |
console.log(cat.name); // 'Fuffy' |
# Encapsulation、Inheritance、Polymorphism(封装、继承、多态)
封装、继承、多态是面向对象编程中的重要概念。
// 封装 | |
class Person { | |
constructor(name) { | |
this._name = name; | |
} | |
get name() { | |
return this._name.toUpperCase(); | |
} | |
set name(newName) { | |
this._name = newName; | |
} | |
} | |
const person = new Person('John'); | |
console.log(person.name); // 'JOHN' | |
person.name = 'Lisa'; | |
console.log(person.name); // 'LISA' | |
// 继承 | |
class Shape { | |
constructor(color) { | |
this.color = color; | |
} | |
draw() { | |
console.log('Drawing a shape...'); | |
} | |
} | |
class Circle extends Shape { | |
constructor(color, radius) { | |
super(color); | |
this.radius = radius; | |
} | |
draw() { | |
console.log(`Drawing a ${this.color} circle with radius ${this.radius}.`); | |
} | |
} | |
const circle = new Circle('red', 10); | |
circle.draw(); // 'Drawing a red circle with radius 10.' | |
// 多态 | |
function drawShape(shape) { | |
shape.draw(); | |
} | |
drawShape(new Shape('blue')); // 'Drawing a shape...' | |
drawShape(new Circle('green', 20)); // 'Drawing a green circle with radius 20.' |
# 总结和实战
在本文中,我们介绍了一些 JavaScript 的高级知识点,如高级数据结构和算法、函数式编程、异步编程和面向对象编程。我们还提供了一些代码示例和实战案例,让掘友们更好地理解和掌握这些技术。
# 通过 Promise.all 实现并发请求
function fetchData(urls) { | |
const promises = urls.map((url) => fetch(url)); | |
return Promise.all(promises).then((responses) => | |
Promise.all( | |
responses.map((response) => { | |
if (!response.ok) throw new Error(response.statusText); | |
return response.json(); | |
}) | |
) | |
); | |
} |
# 使用 async/await 实现异步调用
async function getData(url) { | |
const response = await fetch(url); | |
if (!response.ok) throw new Error(response.statusText); | |
const data = await response.json(); | |
return data; | |
} |
# 在面向对象编程中使用工厂模式
class Product { | |
constructor(name, price) { | |
this.name = name; | |
this.price = price; | |
} | |
} | |
class ProductFactory { | |
createProduct(name, price) { | |
return new Product(name, price); | |
} | |
} | |
const productFactory = new ProductFactory(); | |
const product = productFactory.createProduct('Apple', 1); | |
console.log(product.name); // 'Apple' | |
console.log(product.price); // 1 |
以上是一些简单的实战示例,但实际开发中,我们需要更加复杂和具体的案例来应对实际问题。希望本文能够为读者提供一些参考,让大家更好地掌握 JavaScript 的高级用法。