返回
JavaScript 进阶能力,修炼你手写的知识点
前端
2024-01-28 21:47:47
JavaScript 进阶手写知识点指南
1. new 操作符
概述: new 操作符用于创建 JavaScript 对象的实例,同时可以为新创建的对象自动执行构造函数。
原理: 当使用new操作符创建对象时,JavaScript引擎会执行以下步骤:
- 创建一个新的空对象。
- 为新对象分配内部属性[[Prototype]],该属性指向构造函数的原型对象。
- 执行构造函数,并将构造函数的this指向新创建的对象。
- 构造函数执行结束后,将新创建的对象返回给变量或表达式。
示例:
function Person(name, age) {
this.name = name;
this.age = age;
}
const person = new Person("John Doe", 30);
console.log(person.name); // "John Doe"
console.log(person.age); // 30
2. instanceof 操作符
概述: instanceof 操作符用于检测一个对象是否属于某个类的实例。
原理: instanceof 操作符通过以下步骤进行检测:
- 获取对象的[[Prototype]]属性。
- 检查对象的[[Prototype]]属性是否与给定类的原型对象相同。
- 如果相同,则返回true,否则返回false。
示例:
function Person(name, age) {
this.name = name;
this.age = age;
}
const person = new Person("John Doe", 30);
console.log(person instanceof Person); // true
console.log(person instanceof Object); // true
3. 节流防抖
概述: 节流和防抖是两种常用的函数调用优化技术,用于控制函数的执行频率,防止函数被过度调用。
原理:
- 节流:在一定时间间隔内,只允许函数执行一次。如果在该时间间隔内函数再次被调用,则忽略该调用。
- 防抖:在一定时间间隔内,函数只执行一次。如果在该时间间隔内函数再次被调用,则取消上一次调用的计划执行,并重新开始计时。
示例:
// 节流函数
function throttle(func, wait) {
let lastCall = 0;
return function(...args) {
const now = Date.now();
if (now - lastCall >= wait) {
lastCall = now;
func.apply(this, args);
}
};
}
// 防抖函数
function debounce(func, wait) {
let timerId = null;
return function(...args) {
clearTimeout(timerId);
timerId = setTimeout(() => {
func.apply(this, args);
}, wait);
};
}
4. 去重
概述: 去重是指从数组或对象中删除重复的元素,只保留唯一的元素。
原理: 去重的常用方法包括:
- 借助 Set 对象:Set 对象可以自动去除重复元素。
- 使用 indexOf 方法:通过 indexOf 方法查找重复元素,然后删除它们。
- 使用 filter 方法:通过 filter 方法过滤掉重复元素。
示例:
// 使用 Set 对象去重
const arr = [1, 2, 3, 4, 5, 1, 2, 3];
const uniqueArr = [...new Set(arr)];
console.log(uniqueArr); // [1, 2, 3, 4, 5]
// 使用 indexOf 方法去重
const arr = [1, 2, 3, 4, 5, 1, 2, 3];
const uniqueArr = [];
for (let i = 0; i < arr.length; i++) {
if (uniqueArr.indexOf(arr[i]) === -1) {
uniqueArr.push(arr[i]);
}
}
console.log(uniqueArr); // [1, 2, 3, 4, 5]
// 使用 filter 方法去重
const arr = [1, 2, 3, 4, 5, 1, 2, 3];
const uniqueArr = arr.filter((item, index) => arr.indexOf(item) === index);
console.log(uniqueArr); // [1, 2, 3, 4, 5]
5. call、apply、bind
概述: call、apply 和 bind 都是 JavaScript 中用来改变函数调用上下文的方法。
原理:
- call 和 apply:这两种方法都允许你将一个函数的调用上下文设置为指定的对象。
- bind:bind 方法返回一个新的函数,该函数的调用上下文被绑定到指定的对象上。
示例:
// call 方法
const obj = {
name: "John Doe"
};
function greet() {
console.log(`Hello, ${this.name}!`);
}
greet.call(obj); // "Hello, John Doe!"
// apply 方法
const obj = {
name: "John Doe"
};
function greet() {
console.log(`Hello, ${this.name}!`);
}
greet.apply(obj); // "Hello, John Doe!"
// bind 方法
const obj = {
name: "John Doe"
};
function greet() {
console.log(`Hello, ${this.name}!`);
}
const boundGreet = greet.bind(obj);
boundGreet(); // "Hello, John Doe!"
6. 深拷贝
概述: 深拷贝是指创建一个新对象,该对象包含原始对象的副本,包括原始对象的所有属性和嵌套对象。
原理: 深拷贝的常用方法包括:
- 使用 JSON.parse() 和 JSON.stringify():这两种方法可以将对象转换为 JSON 字符串,然后再将 JSON 字符串解析回对象。
- 使用递归:通过递归的方式,将原始对象的所有属性和嵌套对象复制到新对象中。
示例:
// 使用 JSON.parse() 和 JSON.stringify() 进行深拷贝
const obj = {
name: "John Doe",
age: 30,
address: {
street: "123 Main Street",
city: "Anytown",
state: "CA",
zip: "12345"
}
};
const copyObj = JSON.parse(JSON.stringify(obj));
console.log(copyObj);
// 使用递归进行深拷贝
const obj = {
name: "John Doe",
age: 30,
address: {
street: "123 Main Street",
city: "Anytown",
state: "CA",
zip: "12345"
}
};
function deepCopy(obj) {
if (typeof obj === "object") {
const copyObj = {};
for (const key in obj) {
copyObj[key] = deepCopy(obj[key]);
}
return copyObj;
} else {
return obj;
}
}
const copyObj = deepCopy(obj);
console.log(copyObj);