JavaScript小知识点汇总,助力代码提升
2023-09-06 21:45:42
let在for循环中的特殊行为
在JavaScript中,let变量的作用域是词法作用域,即变量的作用域由其所在的代码块决定。在for循环中,每一轮循环都会创建一个新的代码块,因此let变量在每次循环中都是一个新的变量。
for (let i = 0; i < 3; i++) {
console.log(i); // 0 1 2
}
console.log(i); // ReferenceError: i is not defined
上例中,let变量i在每次循环中都是一个新的变量,因此在循环结束后,i变量就消失了。
this的指向
在JavaScript中,this指向当前执行代码的对象。在全局作用域中,this指向window对象。在函数中,this指向函数的执行上下文对象。在构造函数中,this指向新创建的对象。
function Person(name) {
this.name = name;
this.greet = function() {
console.log(`Hello, my name is ${this.name}!`);
};
}
const person = new Person('John');
person.greet(); // Hello, my name is John!
上例中,构造函数Person的执行上下文对象是新创建的对象person,因此this指向person对象。greet方法也是person对象的方法,因此this也指向person对象。
闭包
闭包是指一个函数可以访问其父函数的作用域。闭包可以用来封装数据和行为,从而提高代码的可维护性和可重用性。
function createCounter() {
let count = 0;
return function() {
return count++;
};
}
const counter = createCounter();
console.log(counter()); // 0
console.log(counter()); // 1
console.log(counter()); // 2
上例中,createCounter函数返回了一个闭包函数。这个闭包函数可以访问createCounter函数的作用域,因此它可以访问count变量。每次调用闭包函数时,count变量都会增加1。
事件委托
事件委托是一种处理事件的技巧,它可以提高性能并简化代码。事件委托的基本原理是将事件监听器附加到父元素上,而不是子元素上。当子元素发生事件时,事件会冒泡到父元素,然后父元素上的事件监听器就会被触发。
const parent = document.getElementById('parent');
parent.addEventListener('click', (event) => {
const target = event.target;
if (target.tagName === 'BUTTON') {
console.log('Button clicked!');
}
});
上例中,我们将事件监听器附加到了parent元素上。当parent元素或其子元素发生click事件时,事件监听器都会被触发。
异步编程
异步编程是指在不阻塞主线程的情况下执行任务。异步编程可以提高web应用的性能和响应性。
JavaScript提供了多种异步编程技术,包括回调函数、Promise和async/await。
setTimeout(() => {
console.log('This message will be logged after 1 second.');
}, 1000);
fetch('https://example.com/api/data')
.then((response) => response.json())
.then((data) => {
console.log(data);
})
.catch((error) => {
console.log(error);
});
上例中,我们使用了setTimeout函数和fetch API来实现异步编程。setTimeout函数会在1秒后执行指定的回调函数。fetch API可以用来从服务器获取数据。
深拷贝
深拷贝是指将对象的所有属性,包括嵌套的对象,都复制到一个新的对象中。深拷贝可以防止对原始对象的操作影响到副本对象。
const originalObject = {
name: 'John',
age: 30,
address: {
city: 'New York',
state: 'New York'
}
};
const copyObject = JSON.parse(JSON.stringify(originalObject));
originalObject.name = 'Jane';
originalObject.address.city = 'Los Angeles';
console.log(originalObject); // { name: 'Jane', age: 30, address: { city: 'Los Angeles', state: 'New York' } }
console.log(copyObject); // { name: 'John', age: 30, address: { city: 'New York', state: 'New York' } }
上例中,我们使用JSON.parse和JSON.stringify函数来实现深拷贝。JSON.stringify函数将对象转换为JSON字符串,JSON.parse函数将JSON字符串转换为对象。
防抖和节流
防抖和节流都是用来控制函数执行频率的技术。防抖是指在一段时间内只执行一次函数。节流是指在一段时间内只执行一次函数,即使函数被多次调用。
function debounce(func, wait) {
let timeout;
return function() {
const args = arguments;
clearTimeout(timeout);
timeout = setTimeout(() => {
func.apply(this, args);
}, wait);
};
}
function throttle(func, wait) {
let lastCallTime = 0;
return function() {
const args = arguments;
const now = Date.now();
if (now - lastCallTime >= wait) {
func.apply(this, args);
lastCallTime = now;
}
};
}
上例中,debounce函数和throttle函数分别实现了防抖和节流。debounce函数会在一段时间内只执行一次函数,即使函数被多次调用。throttle函数会在一段时间内只执行一次函数,但是如果函数在一段时间内被多次调用,那么函数只会执行一次。