返回

JavaScript小知识点汇总,助力代码提升

前端

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函数会在一段时间内只执行一次函数,但是如果函数在一段时间内被多次调用,那么函数只会执行一次。