在学习JavaScript时,必须了解一些基础知识,比如变量、函数、类、循环等,这些基础知识是我们使用JavaScript的基础。然而,在日常业务发展中,我们需要一些更高级的技能来更好地解决问题。
通过阅读本文,我们来学习一下JS的高级知识点和实际应用技巧,例如高级数据结构和算法、函数式编程、异步编程和面向对象编程等。我将通过代码示例来帮助大家更好地理解这些知识点。同时我也会提供一些实际的案例演示和使用技巧,以便大家更好的应用这些技术。
高级数据结构和算法
使用Map
Map数据结构通常用于存储键值对,可以使用任意类型作为键和值。集合数据结构用于存储唯一值的集合。
// Create a Map object
const map = new Map();
// Set key-value pairs
map.set('name', 'Tom');
map.set('age', 20);
// Get key-value pairs
console.log(map.get('name')); // 'Tom'
console.log(map.get('age')); // 20
// Create a Set object
const set = new Set();
// Add elements
set.add(10);
set.add(20);
set.add(30);
// Remove elements
set.delete(20);
// Check if an element exists
console.log(set.has(10)); // true
console.log(set.has(20)); // false
使用堆、栈和队列
堆和栈是常用的内存分配方式。栈是后进先出(LIFO)的数据结构,堆是动态分配的内存结构。队列是一种先进先出 (FIFO) 数据结构,常用于缓存和并发编程。JavaScript的数组函数可以很好的支持了堆和栈和队列的实现
// Simulate a heap using an array
const arr = [1, 2, 3, 4];
arr.push(5); // Push to the heap
console.log(arr.pop()); // Pop from the heap
// Simulate a stack using an array
const stack = [1, 2, 3, 4];
stack.push(5); // Push to the stack
console.log(stack.pop()); // Pop from the stack
// Simulate a queue using an array
const queue = [1, 2, 3, 4];
queue.push(5); // Push to the queue
console.log(queue.shift()); // Pop from the queue
深度优先搜索和广度优先搜索
深度优先搜索(DFS)和广度优先搜索(BFS)是常用的图遍历算法。 DFS通常用于解决深度优先问题,而BFS适合广度优先问题。
// Depth-first traversal
function dfs(node) {
if (node === null) return;
console.log(node.value); // Print the value of the node
dfs(node.left); // Recursively traverse the left subtree
dfs(node.right); // Recursively traverse the right subtree
}
// Breadth-first traversal
function bfs(node) {
const queue = [node]; // Create a queue and enqueue the root node
while (queue.length) {
const curr = queue.shift(); // Dequeue the first node from the queue
console.log(curr.value); // Print the value of the node
if (curr.left) queue.push(curr.left); // Enqueue the left child of the node
if (curr.right) queue.push(curr.right); // Enqueue the right child of the node
}
}
二叉排序、搜索和查找
二叉快速排序采用分而治之的思想,通过将数组分成更小的块来排序。
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)];
}
// Search algorithm:
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)); // 再参数值
// 柯里化
function curry(func) {
return function curried(...args) {
if (args.length >= func.length) {//func.length返回sum函数的参数数量
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'
在Node.js中使用事件循环和EventEmitter
// Event loop
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 Workers 允许我们将长时间运行的任务移出主线程,以避免阻塞 UI。
// main thread
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'
封装、继承、多态
封装、继承和多态性是面向对象编程中的重要概念。
// 封装
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.'
并发请求
可以通过 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();
})
)
);
}
在面向对象编程中使用工厂模式
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