JavaScript 进阶
在掌握了 JavaScript 的基础知识之后,继续深入学习其高级特性和应用技巧将有助于编写更高效、更优雅的代码。本文将详细介绍 JavaScript 的一些进阶概念和技术。
目录
闭包
闭包是 JavaScript 中一个强大的特性,允许函数访问其外部作用域的变量。闭包是在函数定义时而不是在函数调用时创建的。
function outerFunction(outerVariable) {
return function innerFunction(innerVariable) {
console.log("Outer variable: " + outerVariable);
console.log("Inner variable: " + innerVariable);
}
}
const newFunction = outerFunction("outside");
newFunction("inside");
在这个例子中,innerFunction
访问了 outerFunction
的变量 outerVariable
,这就是闭包的体现。
原型与继承
JavaScript 是基于原型的面向对象语言,每个对象都有一个原型对象。对象可以从原型对象继承属性和方法。
原型链
每个 JavaScript 对象都有一个 __proto__
属性,指向其原型对象。这个原型对象也有自己的原型,形成一个原型链。
function Person(name) {
this.name = name;
}
Person.prototype.greet = function() {
console.log("Hello, " + this.name);
}
const alice = new Person("Alice");
alice.greet(); // Hello, Alice
继承
可以通过 Object.create
或 class
关键字实现继承。
class Animal {
constructor(name) {
this.name = name;
}
speak() {
console.log(this.name + " makes a noise.");
}
}
class Dog extends Animal {
speak() {
console.log(this.name + " barks.");
}
}
const dog = new Dog("Rex");
dog.speak(); // Rex barks.
高级函数
高阶函数
高阶函数是指接受一个或多个函数作为参数,或者返回一个函数作为结果的函数。
function add(a, b) {
return a + b;
}
function operate(a, b, operation) {
return operation(a, b);
}
console.log(operate(5, 3, add)); // 8
柯里化
柯里化是将一个多参数函数转换成一系列使用一个参数的函数的技术。
function curryAdd(a) {
return function(b) {
return a + b;
}
}
const add5 = curryAdd(5);
console.log(add5(3)); // 8
函数组合
函数组合是将多个函数组合成一个函数,其中每个函数的输出作为下一个函数的输入。
function compose(...functions) {
return function(arg) {
return functions.reduceRight((acc, fn) => fn(acc), arg);
}
}
const add1 = x => x + 1;
const double = x => x * 2;
const add1AndDouble = compose(double, add1);
console.log(add1AndDouble(3)); // 8
异步编程
Promise
Promise 是一种用于处理异步操作的对象。它表示一个异步操作的最终完成或失败及其结果值。
let promise = new Promise(function(resolve, reject) {
setTimeout(function() {
resolve("Promise resolved");
}, 1000);
});
promise.then(function(data) {
console.log(data);
}).catch(function(error) {
console.error(error);
});
async/await
async
和 await
是基于 Promise 的语法糖,使异步代码看起来像同步代码。
async function fetchData() {
let data = await new Promise(function(resolve) {
setTimeout(function() {
resolve("Data fetched with async/await");
}, 1000);
});
console.log(data);
}
fetchData();
生成器
生成器是一种可以在执行过程中暂停和恢复的函数。生成器函数使用 function*
语法。
function* generator() {
yield 1;
yield 2;
yield 3;
}
const gen = generator();
console.log(gen.next().value); // 1
console.log(gen.next().value); // 2
console.log(gen.next().value); // 3
模块化
ES6 模块
ES6 引入了模块化机制,允许将代码拆分成多个文件。
// 导出模块(export.js)
export function greet() {
console.log("Hello, world!");
}
// 导入模块(import.js)
import { greet } from './export.js';
greet(); // Hello, world!
CommonJS
CommonJS 是 Node.js 中使用的模块系统。
// 导出模块(module.js)
module.exports = {
greet: function() {
console.log("Hello, world!");
}
};
// 导入模块(main.js)
const { greet } = require('./module');
greet(); // Hello, world!
设计模式
单例模式
单例模式确保一个类只有一个实例,并提供全局访问。
class Singleton {
constructor() {
if (!Singleton.instance) {
Singleton.instance = this;
}
return Singleton.instance;
}
}
const instance1 = new Singleton();
const instance2 = new Singleton();
console.log(instance1 === instance2); // true
观察者模式
观察者模式定义对象间的一对多关系,当一个对象的状态发生变化时,所有依赖于它的对象都会收到通知并自动更新。
class Subject {
constructor() {
this.observers = [];
}
addObserver(observer) {
this.observers.push(observer);
}
notifyObservers(message) {
this.observers.forEach(observer => observer.update(message));
}
}
class Observer {
update(message) {
console.log("Received message: " + message);
}
}
const subject = new Subject();
const observer1 = new Observer();
const observer2 = new Observer();
subject.addObserver(observer1);
subject.addObserver(observer2);
subject.notifyObservers("Hello, Observers!");
工厂模式
工厂模式用于创建对象的接口,让子类决定实例化哪个类。
class Animal {
constructor(name) {
this.name = name;
}
speak() {
console.log(this.name + " makes a noise.");
}
}
class Dog extends Animal {
speak() {
console.log(this.name + " barks.");
}
}
class Cat extends Animal {
speak() {
console.log(this.name + " meows.");
}
}
class AnimalFactory {
createAnimal(type, name) {
switch(type) {
case 'dog':
return new Dog(name);
case 'cat':
return new Cat(name);
default:
return new Animal(name);
}
}
}
const factory = new AnimalFactory();
const dog = factory.createAnimal('dog', 'Rex');
dog.speak(); // Rex barks.
性能优化
减少重绘与重排
减少 DOM 的重绘和重排可以显著提高性能。避免频繁地操作 DOM 和使用文档片段(Document Fragment)是常见的方法。
const fragment = document.createDocumentFragment();
for (let i = 0; i < 1000; i++) {
const div = document.createElement('div');
fragment.appendChild(div);
}
document.body.appendChild(fragment);
懒加载
懒加载是指在需要的时候才加载资源,以提高初始加载性能。
document.addEventListener("scroll", function() {
const lazyImages = document.querySelectorAll("img.lazy");
lazyImages.forEach(img => {
if (img.getBoundingClientRect().top < window.innerHeight