js 学习笔记1

64 阅读2分钟
  • ||= 赋值,仅在变量为 null、undefined 或假值(如 0 false '')时才会赋默认值

    let num = 0;
    num ||= 8  // num = 8
    
  • ??= 赋值,仅在变量为 null、undefined 才会赋默认值

    let num;
    num ??= 8  // num = 8
    
  • ?? 空值合并操作符 在变量为 null 或 undefined 时提供默认值

    const value = null;
    const result = value ?? 'default';
    console.log(result); // 'default'
    
    
  • 对象数组排序

    let users = [{ name: 'Alice', age: 25 }, { name: 'Bob', age: 20 }]
    users.sort((a, b) => a.age - b.age) 
    // 升序 改变原数组 users = [{ name: 'Bob', age: 20 }, { name: 'Alice', age: 25 }]
    
  • 动态导入,仅在需要时加载模块,从而减少初始加载时间

    const loadModule = async () => {
     const module = await import('./myModule.js');
     module.default(); // 调用默认导出的函数
    };
    loadModule();
    
  • 带对象解构的默认参数

    function createUser({ name = 'Guest', age = 18 } = {}) {
     console.log(name, age);
    }
    createUser();               // Guest 18
    createUser({ name: 'Alice' }); // Alice 18
    
  • 浅拷贝方法 修改原始对象的基本类型属性不会影响拷贝对象 修改原始对象中引用类型的属性会影响拷贝对象

    // 对象
    const original = { a: 1, b: { c: 2 } }
    const copy1 = { ...original }    // 展开运算符
    const copy2 = Object.assign({}, original)    // Object.assign()
    original.b.c = 3
    original.a = 11
    console.log(original) // { a: 11, b: { c: 3 } }
    console.log(copy1) // { a: 1, b: { c: 3 } }
    console.log(copy2) // { a: 1, b: { c: 3 } }
    
    // 数组
    const original = [1, 2, { a: 3 }]
    const copy = Array.from(original)
    
  • 深拷贝

    1. JSON.parse(JSON.stringify())(最简单但有局限) 不能处理函数、Symbol、undefined 不能处理循环引用 会丢失 Date 对象的类型(变成字符串)

    2. 递归实现

      function deepClone(obj) {
         if (obj === null || typeof obj !== 'object') {
           return obj;
         }
         
         const clone = Array.isArray(obj) ? [] : {};
         
         for (let key in obj) {
           if (obj.hasOwnProperty(key)) {
             clone[key] = deepClone(obj[key]);
           }
         }
         
         return clone;
       }
      
    3. 使用第三方库 Lodash 的 _.cloneDeep() jQuery 的 $.extend(true, {}, obj)

  • 动态创建对象属性

    const key = 'name'
    const value = 'John'
    const obj = { [key]: value }
    console.log(obj); // { name: 'John' }
    
  • 检查对象是否有某个属性

    const obj = { name: 'John' }
    const hasName = 'name' in obj
    console.log(hasName) // true
    
  • 获取对象的所有属性值

    const obj = { a: 1, b: 2 };
    const values = Object.values(obj);
    console.log(values); // [1, 2]
    
  • 获取对象的所有属性键值对

    const obj = { a: 1, b: 2 }
    const entries = Object.entries(obj)
    console.log(entries)  // [['a', 1], ['b', 2]]
    
  • Object.fromEntries() 与 Object.entries()互为逆操作,用于将键值对列表转换为一个对象

  • 防抖函数:最后一次触发后等待n秒执行 触发后等待一段时间执行,如果期间再次触发则重新计时

    // 基本实现 wait时间后,才触发
    function debounce(func, wait) {
      let timer = null
      return function(...args) {
        clearTimeout(timer)
        timer = setTimeout(() => {
          func.apply(this, args)
        }, wait)
      }
    }
    
    // 带有立即执行选项的实现
    function debounce(func, wait, immediate) {
      let timer = null
      return function(...args) {
        const callNow = immediate && !timer
        clearTimeout(timer)
        timer = setTimeout(function() {
          timer = null
          if(!immediate) func.apply(this, args)
        }, wait)
        if(callNow) func.apply(this, args)
      }
    }
    
    // 基本使用
    window.addEventListener('resize', debounce(function() {
      console.log('窗口大小改变了');
    }, 250));
    
    // 带有立即执行
    window.addEventListener('scroll', debounce(function() {
      console.log('滚动事件处理');
    }, 250, true));
    
  • 节流函数:每隔n秒执行一次

    // 时间戳版
    function throttle(func, wait) {
      let previous = 0
      return function(...args) {
        const now = Date.now()
        if(now - previous > wait) {
          func.apply(this, args)
          previous = now
        }
      }
    }
    
    // 定时器版
    function throttle(func, wait) {
      let timer = null
      return function(...args) {
        if(!timer) {
          timer = setTimeout(() => {
            timer = null
            func.apply(this, args)
            timer = null
          }, wait)
        }
      }
    }
    

image.png