js几个实用方法

这篇博客介绍了JavaScript中的几个实用方法,包括数据类型的校验、防抖和节流函数的实现,手机号码的隐藏处理,URL参数的解析以及深拷贝的实现。同时,针对深拷贝的局限性,提供了递归处理的解决方案。此外,还探讨了如何使用lodash库的cloneDeep函数进行深拷贝。
摘要由CSDN通过智能技术生成

记录js几个方法

  1. 校验数据类型
const getType = (obj) => {
  /*
     [object Number]  [object Undefined], toString方法返回的字符串如上所示,故取8到倒数第一个字符
  */

  return Object.prototype.toString.call(obj).slice(8, -1).toLowerCase();
}

// 使用

console.log(getType(1));  // number
console.log(getType(() => { }))  // function
console.log(getType(undefined))  // undefinde
console.log(getType(null))   // null
console.log(getType('1234'))  // string
console.log(getType(false))  // boolean

  1. 防抖 – 防抖是将多次执行变为最后一次执行

const debounce = (() => {
  let timer = null;
  return (callBack, time) => {
    timer && clearTimeout(timer);
    timer = setTimeout(callBack, time)
  }
})()

// 使用
const load = () => {
  debounce(() => {
    console.log('执行')
  }, 800)
}

  1. 节流 – 节流是将多次执行变成每隔一段时间执行

const throttle = (() => {
  let start = 0;
  return (callBack, time) => {
    let now = Date.now();
    if (now - start >= time) {
      start = now;
      callBack();
    }
  }
})()

// 使用
const load = () => {
  throttle(() => {
    console.log('执行')
  }, 800)
}

setInterval(() => {
  console.log(222)
  load();
},300)

  1. 手机号隐藏

const hiddenMobile = (mobile) => {
  return mobile.replace(/^(\d{3})\d{4}(\d{4})$/, `$1****$2`);
}
// 使用
console.log(hiddenMobile('12345678912'))

  1. 解析url参数

URLSearchParams 接口定义了一些实用的方法来处理 URL 的查询字符串,文档 URLSearchParams


const getParams = (paramsString) => {
    let searchParams =  new URLSearchParams(paramsString);
    let params = {}
    for(let [key, value] of searchParams.entries()) {
      params[key] = value;
    }
    return params;
}
let str1 = '?a=1&b=2';
let str2 = 'c=1&d=2';
console.log(getParams(str1));  // { a: '1', b: '2' }
console.log(getParams(str2));  // { c: '1', d: '2' }

// 组合参数
let str = new URLSearchParams({ c: '1', d: '2' }).toString()
console.log(str); // c=1&d=2

  1. 深拷贝

使用 JSON.parse(JSON.stringify(obj));

存在问题:
我们在使用时应该注意几点问题:

1、如果obj里有函数,undefined,则序列化的结果会把函数, undefined丢失。

2、如果obj里有NaN、Infinity和-Infinity,则序列化的结果会变成null。

3、如果obj里有RegExp、Error对象,则序列化的结果将只得到空对象。

4、如果obj里面存在时间对象,时间对象变成了字符串。

5、JSON.stringify()只能序列化对象的可枚举的自有属性。如果obj中的对象是有构造函数生成的,会丢弃对象的constructor。

6、如果对象中存在循环引用的情况也无法正确实现深拷贝。


let obj = {
  list: [
    {
      a: 1, b: undefined, c: null, d: 0, e: true, f: function () {
        let a = 1, b = 2;
        console.log(a + b);
      }
    }
  ],
  info: {
    a: 1, b: undefined, c: null, d: 0, e: true, f: function () {
      let a = 1, b = 2;
      console.log(a + b);
    },
    time: new Date()
  }
}

let cloneObj = JSON.parse(JSON.stringify(obj));
console.log(cloneObj) 
/*
  {
  list: [ { a: 1, c: null, d: 0, e: true } ],
  info: {
    a: 1,
    c: null,
    d: 0,
    e: true,
    time: '2022-08-30T03:52:31.378Z',
    nan: null
  }
*/
}

递归函数处理


// 处理正则
const getRegExp = re => {
  let flags = '';
  if (re.global) {
    flags += 'g';
  }
  if (re.ignoreCase) {
    flags += 'i';
  }
  if (re.multiline) {
    flags += 'm';
  }
  return flags;
}

const cloneDeep = (parent) => {
  const parents = [], children = [];
  const _clone = parent => {
    if (parent === null || typeof parent !== 'object') {
      return parent;
    }

    let child, proto;
    // getType 函数是上面的第一条的函数
    if (getType(parent) === 'array') {
      // 数组
      child = [];
    } else if (getType(parent) === 'regexp') {
      // 正则
      child = new RegExp(parent.source, getRegExp(parent));
      if (parent.lastIndex) {
        child.lastIndex = parent.lastIndex;
      }
    } else if (getType(parent) === 'date') {
      // Date
      child = new Date(parent.getTime());
    } else {
      // 对象
      // 处理对象原型
      proto = Object.getPrototypeOf(parent);
      // 利用 Object.create() 切断原型链
      child = Object.create(proto);
    }

    // 处理循环引用
    const index = parents.indexOf(parent);
    if (index != -1) {
      // 如果父数组存在本对象,直接返回本对象
      return children[index];
    }
    parents.push(parent);
    children.push(child)
    for (let i in parent) {
      child[i] = _clone(parent[i]);
    }
    return child;
  }
  return _clone(parent);
}

// 测试

let obj = {
  list: [
    {
      a: 1, b: undefined, c: null, d: 0, e: true, f: function () {
        let a = 1, b = 2;
        console.log(a + b);
      }
    }
  ],
  info: {
    a: 1, b: undefined, c: null, d: 0, e: true, f: function () {
      let a = 1, b = 2;
      console.log(a + b);
    },
    time: new Date(),
    g: NaN,
    h: /\d{4}/ig
  }
}

let cloneObj = cloneDeep(obj);
console.log(cloneObj);

/**
 * {
  list: [ { a: 1, b: undefined, c: null, d: 0, e: true, f: [Function: f] } ],
  info: {
    a: 1,
    b: undefined,
    c: null,
    d: 0,
    e: true,
    f: [Function: f],
    time: 2022-08-31T06:43:41.923Z,
    g: NaN,
    h: /\d{4}/gi
  }
}
 * 
*/

使用lodash库 cloneDeep()函数. 文档lodash

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值