# 工具函数

# 千分符 1

function format(num) {
  let arr = [];
  let str = "" + num;
  let intPart = "";
  let digitPart = "";
  let count = "";
  if (str.indexOf(".") !== -1) {
    intPart = str.split(".")[0];
    digitPart = str.split(".")[1];
  } else {
    intPart = str;
  }

  count = intPart.length;

  while (count >= 3) {
    arr.unshift(intPart.slice(count - 3, count));
    count -= 3;
  }

  // 如果是不是3的倍数就另外追加到上去
  intPart.length % 3 && arr.unshift(intPart.slice(0, intPart.length % 3));

  if (digitPart.length > 0) {
    return `${arr.toString()}.${digitPart}`;
  } else {
    return arr.toString();
  }
}
//	12,345,678.12
console.log(format(12345678.12));

# 千分符 2

const format = (val, fixedNum = 0) => {
  let _val = "" + Number(val).toFixed(fixedNum);
  if (_val.indexOf(".") !== -1) {
    return _val.replace(/(\d)(?=(\d{3})+\.)/g, "$1,");
  } else {
    return _val.replace(/(?=(?!\b)(\d{3})+$)/g, ",");
  }
};

//  10,000
console.log(format(10000));

# 时间戳转日期

/**
 * 将小于10的值加上零
 * @param {number} value 数字
 * @return {string}
 */
const formatNumber = (value) => `${value < 10 ? "0" + value : value}`;

/**
 * 时间戳转日期
 * @param {number} timestamp 时间戳
 * @param {传入格式} format 必须以Y-M-D h:m:s组成,默认格式为以上
 */
const timeStampToTime = (timestamp, format = "Y-M-D h:m:s") => {
  timestamp = timestamp.toString().length == 10 ? timestamp * 1000 : timestamp;
  const formatArr = ["Y", "M", "D", "h", "m", "s"];
  const date = new Date(timestamp);
  const year = date.getFullYear();
  const month = formatNumber(date.getMonth() + 1);
  const day = formatNumber(date.getDate());
  const hour = formatNumber(date.getHours());
  const minute = formatNumber(date.getMinutes());
  const second = formatNumber(date.getSeconds());
  const time = [year, month, day, hour, minute, second];
  time.forEach((item, index) => {
    format = format.replace(formatArr[index], item);
  });
  return format;
};

//  09:16:08 2019/11/28
console.log(timeStampToTime(1574903768080, "h:m:s Y/M/D "));

# 日期转时间戳

/**
 * 日期转时间戳
 * @param {string} time 日期格式
 * @param {boolean} isUnix 是否是unix格式(10位)
 * @return {number} 时间戳
 */
function timeToTimeStamp(time, isUnix) {
  const date = new Date(time);
  const timestamp = date.getTime();
  return isUnix ? timestamp / 1000 : timestamp;
}

# 本地时钟(每次跑一秒)

/**
 * 加一秒
 * @param {date} time 日期
 */
const runClock = (time) => {
  const timeStamp = timeToTimeStamp(time) + 1000;
  const newestTime = timeStampToTime(timeStamp);
  return newestTime;
};

/**
 * 刷新系统时间
 */
const refreshSystemTime = () => {
  systemTimer = setInterval(() => {
    const newestSystemTime = runClock(systemTime);
    systemTime = newestSystemTime;
    console.log(systemTime);
  }, 1000);
};

let systemTimer = null;
let systemTime = "2019/11/08 09:26:00";
refreshSystemTime();

# 倒计时(根据本地时钟)

本地时钟需要同时运行,如果不运行,那么取网络时间,以下为依靠本地时钟代码

//	....本地时钟代码
const clearAllTimer = () => {
  clearInterval(systemTimer);
  clearInterval(countDownTimer);
};

/**
 * 格式化倒计时
 * @param {timestamp} time 时间戳
 * Note: 按照 {天,时,分,秒}返回
 */
const formatCountDownTime = (time) => {
  const remainTime = parseInt(time / 1000);
  const day = parseInt(remainTime / (24 * 3600));
  const hour = formatNumber(parseInt((remainTime - day * 24 * 3600) / 3600));
  const minute = formatNumber(parseInt((remainTime - day * 24 * 3600 - hour * 3600) / 60));
  const second = formatNumber(parseInt(remainTime % 60));
  return { day, hour, minute, second };
};

/**
 * 倒计时计算
 * @param {time} endPoint 结束时间
 * Description: 返回还剩多少天多少小时多少分多少秒
 * Note:格式{ day: 0, hour: '00', minute: '00', second: '09' }
 */
const countDownCalculate = (endPoint) => {
  const deadLine = new Date(endPoint).getTime();
  countDownTimer = setInterval(() => {
    const systemTimeStamp = timeToTimeStamp(systemTime);
    const countDownTime = deadLine - systemTimeStamp;
    if (countDownTime == 0 || countDownTime < 0) {
      clearAllTimer();
    }
    const countDown = formatCountDownTime(countDownTime);
    console.log(countDown);
  }, 1000);
};

let systemTimer = null;
let systemTime = "2019/11/08 09:26:00";

let countDownTimer = null;
let countDownTime = "";
let endTime = "2019/11/08 09:26:10";

refreshSystemTime();
countDownCalculate(endTime);

# 是否是 11 位有效手机号

/**
 * 判断是否是11位有效手机号
 * @param {number} phoneNum 手机号
 */
function isValidPhone(phoneNum) {
  const phoneReg = /^[1][3,4,5,7,8][0-9]{9}$/;
  if (!phoneReg.test(phoneNum)) {
    return false;
  } else {
    return true;
  }
}

# 取整数

//	方法一:parseInt(向下取整)
parseInt(12.56); //12
//	方法二:Math.floor(向下取整)
Math.floor(12.56); // 12
//	方法三:Math.ceil(向上取整)
Math.ceil(12.56); // 13
//	方法四:字符串分隔(向下取整)
const formatInt(num)=>{
    const _num = ''+num;
    return _num.split('.')[0];
}

# 取出一组数组中的最大和最小值

Math.min.apply(null, [1, 2, 3, 4, 5]); // 5
Math.max.apply(null, [1, 2, 3, 4, 5]); // 1

# 给字符串去空格,并且按空格分隔为字符串数组

const str = "1 2 3";
const splitWordWithoutSpace = function(str) {
  const splitWordArr = str.split(" ");
  const splitWord = splitWordArr.filter((item) => item.length > 0);
  return splitWord;
};
//  [ '1', '2', '3' ]
console.log(splitWordWithoutSpace(str));

# 比较两个函数是否相等

/**
 * 判断2个函数是否相等
 * @param {function} func1 函数1
 * @param {function} func2 函数2
 * Note: 包括函数名和函数体
 */
const isEqualFunc = function(func1, func2) {
  const strFunc1 = func1.toString().replace(/\s/g, "");
  const strFunc2 = func2.toString().replace(/\s/g, "");
  return strFunc1 === strFunc2;
};

function add() {
  return 1 + 2;
}
// true
console.log(isEqualFunc(add, add));

# 生成 UID

/**
 * 有一定的几率重复,要求高的场景还是使用专门的uid库
 */
const getUid = function() {
  const S4 = function() {
    return (((1 + Math.random()) * 0x10000) | 0).toString(16).substring(1);
  };
  return S4() + S4() + "-" + S4() + "-" + S4() + "-" + S4() + "-" + S4() + S4() + S4();
};
// 13bd2f62-4b3a-3967-1d65-a7b1ca947079
console.log(getUid());

# 把文件大小从 byte 转为其他单位

const toFileSize = function(size) {
  let B = function() {
    return size + "B";
  };
  let KB = function() {
    return (size / 1024).toFixed(2) + "KB";
  };
  let MB = function() {
    return (size / (1024 * 1024)).toFixed(2) + "MB";
  };
  let GB = function() {
    return (size / (1024 * 1024 * 1024)).toFixed(2) + "GB";
  };
  return size < 1024 ? B() : size < 1024 * 1024 ? KB() : size < 1024 * 1024 * 1024 ? MB() : GB();
};

// 1.00KB
console.log(toFileSize(1024));

# 对象数组深拷贝(适用于内容是文件)

const deepCopy = (source) => {
  const arr = source.map((item) => {
    let obj = {};
    for (let i in item) {
      obj[i] = item[i];
    }
    return obj;
  });
  return arr;
};

# 深拷贝(适合多层数据)

const deepClone = (obj) => {
  let cloneObj = Array.isArray(obj) ? [] : {};
  if (obj && typeof obj === "object") {
    for (var key in obj) {
      if (obj.hasOwnProperty(key)) {
        if (obj[key] && typeof obj[key] === "object") {
          cloneObj[key] = deepClone(obj[key]);
        } else {
          cloneObj[key] = obj[key];
        }
      }
    }
  }
  return cloneObj;
}

# 生成某个范围内的随机数(整数)

在数轴上随机选一个点(闭区间)

const runRandom = (min, max) => {
  const range = max - min;
  return min + Math.round(Math.random() * range);
};

# 交换数组元素

const swapElement = (fromIndex, toIndex, arr) => {
  const temp = arr[fromIndex];
  arr.splice(fromIndex, 1);
  arr.splice(toIndex, 0, temp);
  return arr;
};

# 正则

//	必须是数字且最多输入两位
/^(\-)?\d*(\.)?\d{0,2}$/;

# 左补零

/**
 *
 * @param {number} num 传入的数
 * @param {number} keepDigit 要保持的位数
 * @return  {string} 补零之后返回的字符串
 */
const leftPadZero = (num, keepDigit) => {
  num = "" + num;
  if (num.length < keepDigit) {
    return "0".repeat(keepDigit - num.length) + num;
  } else {
    return num;
  }
};

# 生成复制文本(点击复制文本)

constc copyText= function(data){
    var oInput = document.createElement("input");
    oInput.value = data;
    document.body.appendChild(oInput);
    oInput.select();
    document.execCommand("Copy");
    oInput.className = "oInput";
    oInput.style.display = "none";
 }

# 解析并渲染 html

# vue

//	使用html
<div v-html="consoleWrite"
   class="cmm-wrapper">
</div>
//	保留源代码中的换行并且保留空白格 /r/n
.cmm-wrapper {
  white-space: pre-wrap;
}

# vh 和 px 的单位换算

min-height: calc(100vh - 180px);

# 将符合"A=a;B=b;C=c"的字符串转为json对象

/**
 * 将符合"A=a;B=b;C=c"的字符串转为json对象,此处返回{A:"a", B:"b",C:"c"}
 * @param {string} str 字符串
 * @param {string} separator 分隔符,是以";"分隔还是","分隔
 */
const strToJsonObj = (str, separator)=>{
  let obj = {};
  str.split(seperator).map(item => {
    const itemSplit = item.split("=");
    obj[itemSplit[0]] = itemSplit[1];
  });
  return obj;
}

# 将数字转换为 K,W,M,B 的单位

K -> 千 W -> 万 M -> 百万 B-> 亿



/**
 * 将数字转换为K,W,M,B的单位
 * @param {number} num 数字
 * @param {number} keepDigit 转换单位之后数字要保留的小数位,默认保留1位
 */
const toQuantityUnit = (num, keepDigit = 1) => {
  let K = function() {
    return `${(num / 1000).toFixed(keepDigit)}K`;
  };
  let W = function() {
    return `${(num / 10000).toFixed(keepDigit)}W`;
  };

  let M = function() {
    return `${(num / 1000000).toFixed(keepDigit)}M`;
  };

  let B = function() {
    return `${(num / 1000000000).toFixed(keepDigit)}B`;
  };
  return num < 1000
    ? num
    : num < 10000
    ? K()
    : num < 1000000
    ? W()
    : num < 1000000000
    ? M()
    : B();
};

# 校验字符串是否能够转为 json

/**
 *
 * 将字符串转为json
 * 如果不能转为json就返回false
 * @param {string} str 要校验的json字符串
 */
const tryParseJSON = (str) => {
  const _str = str.replace(/\r\n/g, "");
  try {
    var o = JSON.parse(_str);
    if (o && typeof o === "object") {
      return o;
    }
  } catch (e) {}
  return false;
};