薛定猫的……饿!

vuePress-theme-reco 叶江怀    2020 - 2021
薛定猫的……饿! 薛定猫的……饿!

Choose mode

  • dark
  • auto
  • light
首页
技术相关
  • Css
  • Javascript
  • Vue
  • React
  • Node
  • 数据结构
  • 数据库
  • 其他
导航
时间轴
简历
掘金
github
author-avatar

叶江怀

51

Article

27

Tag

首页
技术相关
  • Css
  • Javascript
  • Vue
  • React
  • Node
  • 数据结构
  • 数据库
  • 其他
导航
时间轴
简历
掘金
github

JS 常用技术

vuePress-theme-reco 叶江怀    2020 - 2021

JS 常用技术


叶江怀 2021-02-18 javascript

# JS 常用技术

# 防抖

/*
      防抖:
        @params:
          func[function]:最后要触发执行的函数
          wait[number]:频繁设定的界限
          immediate[boolean]:默认多次操作,我们识别的是最后一次,但是immediate=true,让其识别第一次
        @return
          可以被调用执行的函数
 */
export const debounce = (func, wait = 200, immediate = false) => {
  let timer = null;
  return (anonymous = (...parmas) => {
    let now = immediate && !timer;
    // 每次点击时都有清楚掉原有的定时器
    clearTimeout(timer);
    timer = setTimeout(() => {
      timer = null; //垃圾回收机制
      // 判断时候二次触发
      !immediate ? func.call(this, ...parmas) : null;
    }, wait);
    !now ? func.call(this, ...parmas) : null;
  });
};
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23

# 节流

/*
      @params:
          func[function]:最后要触发执行的函数
          wait[number]:触发的频率
        @return
          可以被调用执行的函数
*/
throttle = (func, wait = 300) => {
  let timer = null,
    previous = 0; //记录上一次操作时间
  return function anonymouse(...params) {
    let now = new Date(), //记录当前时间
      remaining = wait - (now - previous); //记录还差多久达到我们一次触发的频率
    if (remaining <= 0) {
      //两次操作的间隔时间已经超过wait了
      window.clearInterval(timer);
      timer = null;
      previous = now;
      func.call(this, ...params);
    } else if (!timer) {
      //两次操作的间隔时间还不符合触发的频率
      timer = setTimeout(() => {
        timer = null;
        previous = new Date();
        func.call(this, ...params);
      }, remaining);
    }
  };
};
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29

# 深拷贝

// 1、利用JSON进行深拷贝
export const deepClone1 = (obj) => {
  return JSON.parse(JSON.stringify(obj));
};
// 2、利用递归进行深拷贝
export const deepClone = (obj, cache = new Set()) => {
  //深克隆 cache处理self属性,防止死递归
  //只有数组和对象我们再处理深克隆,其余的按照浅克隆
  let type = toType(obj);
  if (!/^(array|object)$/.test(type)) return this.clone(obj);
  if (cache.has(obj)) return obj;
  cache.add(obj);
  let keys = this.getOwnProperty(obj),
    clone = {};
  type === "array" ? (clone = []) : null;

  keys.forEach((key) => {
    clone[key] = this.deepClone(obj[key], cache);
  });
  return clone;
};
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21

# 数组扁平化处理

let arr = [1, 2, [3, 4, [5, [6]]]];
// 1、使用flat
export const flatArr = (arr) => {
  return arr.flat(Infinity); //flat参数为指定要提取嵌套数组的结构深度,默认值为 1
};
// 2、使用reduce
function reduceArr(arr) {
  return arr.reduce((prev, cur) => {
    return prev.concat(Array.isArray(cur) ? reduceArr(cur) : cur);
  }, []);
}
1
2
3
4
5
6
7
8
9
10
11

# 数组去重

const arr = [1, 1, "1", 17, true, true, false, false, "true", "a", {}, {}];
// => [1, '1', 17, true, false, 'true', 'a', {}, {}]
// 1、利用嵌套循环和splice
export const unique1 = (arr) => {
  let len = arr.length;
  for (let i = 0; i < len; i++) {
    for (let j = i + 1; j < len; j++) {
      if (arr[i] === arr[j]) {
        arr.splice(j, 1);
        // 每删除一个树,j--保证j的值经过自加后不变。同时,len--,减少循环次数提升性能
        len--;
        j--;
      }
    }
  }
  return arr;
};
// 利用indexOf
export const unique2 = (arr) => {
  const res = [];
  for (let i = 0; i < arr.length; i++) {
    if (res.indexOf(arr[i]) === -1) res.push(arr[i]);
  }
  return res;
};
// 利用es6的Set
export const unique3 = (arr) => {
  return Array.from(new Set(arr));
};
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29

# 函数珂里化

export const add = () => {
  let _args = [...arguments];
  fn = () => {
    _args.push(...arguments);
    return fn;
  };
  fn.toString = () => {
    return _args.reduce((sum, cur) => sum + cur);
  };
  return fn;
};
1
2
3
4
5
6
7
8
9
10
11

# AJAX

export const getJSON = (url) => {
  return new Promise((resolve, reject) => {
    const xhr = XMLHttpRequest
      ? new XMLHttpRequest()
      : new ActiveXObject("Mscrosoft.XMLHttp");
    xhr.open("GET", url, false);
    xhr.setRequestHeader("Accept", "application/json");
    xhr.onreadystatechange = function() {
      if (xhr.readyState !== 4) return;
      if (xhr.status === 200 || xhr.status === 304) {
        resolve(xhr.responseText);
      } else {
        reject(new Error(xhr.responseText));
      }
    };
    xhr.send();
  });
};
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18

# 图片懒加载

lazyload = () => {
  const imgs = document.getElementsByTagName("img");
  const len = imgs.length;
  // 视口的高度
  const viewHeight = document.documentElement.clientHeight;
  // 滚动条高度
  const scrollHeight =
    document.documentElement.scrollTop || document.body.scrollTop;
  for (let i = 0; i < len; i++) {
    const offsetHeight = imgs[i].offsetTop;
    if (offsetHeight < viewHeight + scrollHeight) {
      const src = imgs[i].dataset.src;
      imgs[i].src = src;
    }
  }
};

// 可以使用节流优化一下
window.addEventListener("scroll", lazyload);
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
  • 防抖
  • 节流
  • 深拷贝
  • 数组扁平化处理
  • 数组去重
  • 函数珂里化
  • AJAX
  • 图片懒加载