博客 / 詳情

返回

一些有用的javascript函數

作者:不愛喝橙子汁

/**
 * 類型檢測函數
 * 為typeof關鍵字的增強版,可以準確判斷null,date類型
 * 原理是使用V8引擎最初的toString方法觀察數據類型
 * @author 不愛喝橙子汁
 * @version 1.0.0
 * @param {Object} obj 任意對象,例如null,undefined,date
 * @return {String} 類型的全小寫字符串
 */
function type(obj) {
   return Object.prototype.toString.call(obj).slice(8,-1).toLowerCase(); 
}
/**
 * 節流
 * 在給定時間內只有第一次的操作會返回結果
 * 結合了防抖的思路:在delay時間內生成定時器,一旦到了delay的時間就返回結果
 * 當用户只點擊了一次的時候,在delay時間後得到結果
 * 當用户點擊了多次的時候,在delay時間後得到第一次的結果,其餘的被節流閥忽視掉
 * @author 不愛喝橙子汁
 * @version 1.0.0
 * @param {Function} fn 要包裝的回調函數
 * @param {number} delay 延遲時間,單位ms,默認500
 * @return {Function} 被節流函數劫持的新的函數
 */

function throttle(fn, delay = 500) {
  let last = 0;
  let timer = null;
  
  return function () { 
    let args = arguments;
    let now = +new Date();
    let context = this;

    if (now - last < delay) {
      clearTimeout(timer);
      timer = setTimeout(() => {
        last = now;
        fn.apply(context, args);
      }, delay);
    } else {
        last = now;
        fn.apply(context, args);
    }
  }
}
/**
 * 防抖
 * 在delay時間後得到結果
 * 如果沒等到delay的時間一直觸發則永遠也得不到結果
 * @author 不愛喝橙子汁
 * @version 1.0.0
 * @param {Function} fn 要包裝的回調函數
 * @param {number} delay 延遲時間,單位ms,默認500
 * @return {Function} 被防抖函數劫持的新的函數
 */
function debounce(fn, delay = 500) {
  let timer = null;
  return function () {
    let args = arguments;

    if(timer) {
        clearTimeout(timer);
    }

    timer = setTimeout(() => {
      fn.apply(this, args);
    }, delay);
  }
}
/**
 * 獲取地圖上兩點間距離。單位:米
 * @param {lat1} 第一個點的緯度
 * @param {lon1} 第一個點的經度
 * @param {lat2} 第二個點的緯度
 * @param {lon2} 第二個點的經度
 * @author 不愛喝橙子汁
 */
export function getDistance(lat1, lon1, lat2, lon2) {
  const radLat1 = (lat1 * Math.PI) / 180.0;
  const radLat2 = (lat2 * Math.PI) / 180.0;
  const a = radLat1 - radLat2;
  const b = (lon1 * Math.PI) / 180.0 - (lon2 * Math.PI) / 180.0;
  let s = 2 * Math.asin(Math.sqrt(Math.pow(Math.sin(a / 2), 2) + Math.cos(radLat1) * Math.cos(radLat2) * Math.pow(Math.sin(b / 2), 2)));
  s = s * 6378137;
  s = Math.round(s * 10000) / 10000;
  return s;
}
// 把若干數組按指定的字段名進行分組
function groupBy(list, propName) {
  return list.reduce((acc, item) => {
    const key = item[propName];
    if (!acc[key]) {
      acc[key] = [];
    }
    acc[key].push(item);
    return acc;
  }, {});
}
// 深拷貝對象
function deepClone(obj) {
  if (obj === null) return null;
  if (typeof obj !== 'object') return obj;
  if (obj instanceof Date) {
    let date = new Date();
    date.setTime(obj.getTime());
    return date;
  }
  if (obj instanceof RegExp) {
    let re = new RegExp(obj.source);
    re.lastIndex = obj.lastIndex;
    return re;
  }
  let newObj = new obj.constructor();
  for (let key in obj) {
    if (obj.hasOwnProperty(key)) {
      newObj[key] = deepClone(obj[key]);
    }
  }
  return newObj;
}
/**
 * 提取若干數組中指定字段組合成一個新數組
 */
function extractProps(arr, prop) {
  return arr.map((item) => item[prop]);
}
/**
 * 提取對象中的指定的屬性,返回一個新對象
 */
function pickProps(obj, props) {
  if (typeof obj !== 'object') {
    return obj;
  }
  const newObj = {};
  props.forEach((prop) => {
    newObj[prop] = obj[prop];
  });
  return newObj;
}
user avatar
0 位用戶收藏了這個故事!

發佈 評論

Some HTML is okay.