js基礎之程式碼篇1.0

Skyshine發表於2020-01-21

防抖與節流

防抖:動作繫結事件,動作發生後一定時間後觸發事件,在這段時間內,如果該動作又發生,則重新等待一定時間再觸發事件。

function debounce(func, time) {
  let timer = null;
  return () => {
    clearTimeout(timer);
    timer = setTimeout(()=> {
      func.apply(this, arguments)
    }, time);
  }
}
複製程式碼

節流:動作繫結事件,動作發生後一段時間後觸發事件,在這段時間內,如果動作又發生,則無視該動作,直到事件執行完後,才能重新觸發。

function throtte(func, time){
  let activeTime = 0;
  return () => {
    const current = Date.now();
    if(current - activeTime > time) {
      func.apply(this, arguments);
      activeTime = Date.now();
    }
  }
}
複製程式碼

柯里化

簡單說就是把多形參的函式轉換為可以一個一個接收引數的函式,即如下

add(x,y) => curryAdd(x)(y)
複製程式碼
function curry(f){
  var total = f.length
  var args = []
  return function() {
    args.push(...arguments)
    if (args.length < total) {
      return arguments.callee
    } else {
      var res = f.apply(this, args)
      args = [] // 需要清理args
      return res
    }
  }
}

function add(x,y) {
  return x+y
}

var curryAdd=curry(add)

curryAdd(1)(2) // 3
curryAdd(1,2) 
複製程式碼

函式組合

組合函式指的是將代表各個動作的多個函式合併成一個函式

function componse(...funcs) {
  return function() {
    var result = funcs[0].apply(this, arguments)
    for (var i = 1; i < funcs.length; i++) {
      result = funcs[i].call(this, result)
    }
    return result
  }
}

function f1(x) {
  return x + 1
}

function f2(x) {
  return x * 2
}

var f = componse(f1, f2)
f(1) // 4
複製程式碼

深拷貝

// 型別整合
const mapTag = '[object Map]'
const setTag = '[object Set]'
const arrayTag = '[object Array]'
const objectTag = '[object Object]'

const boolTag = '[object Boolean]'
const dateTag = '[object Date]'
const errorTag = '[object Error]'
const numberTag = '[object Number]'
const regexpTag = '[object RegExp]'
const stringTag = '[object String]'
const symbolTag = '[object Symbol]'

const deepTag = [mapTag, setTag, arrayTag, objectTag]
// 判斷原始型別和引用型別
function isObject(target) {
  const type = typeof target
  return target !== null && (type === 'object' || type === 'function')
}
// 獲取克隆物件的型別
function getType(target) {
  return Object.prototype.toString.call(target)
}
// 初始化要克隆的物件
function getInit(target) {
    const Ctor = target.constructor
    return new Ctor()
}
// loadsh使用的遍歷迭代器
function arrayEach(array, iteratee) {
  let index = -1
  const length = array.length

  while (++index < length) {
    if (iteratee(array[index], index, array) === false) {
      break
    }
  }
  return array
}
// 克隆其他不可遍歷型別
function cloneOtherType(targe, type) {
  const Ctor = targe.constructor
  switch (type) {
    case boolTag:
    case numberTag:
    case stringTag:
    case errorTag:
    case dateTag:
      return new Ctor(targe)
    case regexpTag:
      return cloneReg(targe)
    case symbolTag:
      return cloneSymbol(targe)
    default:
      return null
  }
}
// 克隆Symbol
function cloneSymbol(targe) {
  return Object(Symbol.prototype.valueOf.call(targe))
}
// 克隆正則
function cloneReg(targe) {
  const reFlags = /\w*$/
  const result = new targe.constructor(targe.source, reFlags.exec(targe))
  result.lastIndex = targe.lastIndex
  return result
}
function deepClone(value, map=new WeakMap()) {
  let cloneValue, type
  // 判斷引用資料型別
  if (!isObject(value)) {
    return value
  }

  // 初始化
  const type = getType(value)
  if (deepTag.includes(type)) {
    cloneValue = getInit(value)
  } else {
    return cloneOtherType(value, type) 
  }
  // 防止迴圈引用
  if (map.get(value)) {
      return map.get(value)
  }
  map.set(value, cloneValue)

  // 克隆set
  if (type === setTag) {
    value.forEach(value => {
      cloneValue.add(deepClone(value,map))
    })
    return cloneValue
  }

  // 克隆map
  if (type === mapTag) {
    value.forEach((value, key) => {
      cloneValue.set(key, deepClone(value,map))
    })
    return cloneValue
  }

  // 克隆物件和陣列
  const props = type === arrayTag ? undefined : Object.keys(value)
  arrayEach(props || value, (value, key) => {
      if (props) {
          key = value
      }
      cloneValue[key] = deepClone(value[key], map)
  })
  return cloneValue
}

export default deepClone
複製程式碼

new

1. 建立一個全新的物件。
2. 這個新物件會被執行 [[Prototype]] 連線。
3. 這個新物件會繫結到函式呼叫的 this4. 如果函式沒有返回其他物件,那麼 new 表示式中的函式呼叫會自動返回這個新物件。
複製程式碼
function _new(fn, ...arg) {
  const obj = Object.create(fn.prototype);
  const ret = fn.apply(obj, arg);
  return ret instanceof Object ? ret : obj;
}
複製程式碼

千分位

1、正則

function fmoney(num: number){
  let [integer, decimal] = String(num).split('.');
  let regExp = /\d{1,3}(?=(\d{3})+$)/g;
  integer = integer.replace(regExp, '$&,');
  return `${integer}${decimal === undefined ? '': '.'+decimal}`;
}
複製程式碼

2、reduce

function fmoney(num: number){
  let arr = String(num).split('.');
  let char = arr[0].split('').reverse();   
  let IntStr = char.reduce((acc, value, index) => {
      return `${index % 3 === 0 ? String(value)+',' : String(value)}${acc}`;
  }, '').slice(0, -1);
  return `${IntStr}${arr[1]? '.'+arr[1] : '' }`;
}
複製程式碼

陣列扁平化

遞迴

function flat (arr, results = []) {
  arr.forEach((item, index) => {
    if (item instanceof Array) {
      flat(item, reuslts)
    } else {
      results.push(item)
    }
  })
  return results
}
複製程式碼
var arr = [1, [[2, 3], 4], [5, 6]];

var flat = function* (a) {
  var length = a.length;
  for (var i = 0; i < length; i++) {
    var item = a[i];
    if (typeof item !== 'number') {
      yield* flat(item);
    } else {
      yield item;
    }
  }
};

for (var f of flat(arr)) {
  console.log(f);
}
// 1, 2, 3, 4, 5, 6
複製程式碼

ES6

[1, [1,2]].flat(Infinity)
複製程式碼

相關文章