1. 实现日期格式化函数

  1. dateFormat(new Date('2020-12-01'), 'yyyy/MM/dd') // 2020/12/01
  2. dateFormat(new Date('2020-04-01'), 'yyyy/MM/dd') // 2020/04/01
  3. dateFormat(new Date('2020-04-01'), 'yyyy年MM月dd日') // 2020年04月01日
  1. const dateFormat = (dateInput, format)=>{
  2. var day = dateInput.getDate()
  3. var month = dateInput.getMonth() + 1
  4. var year = dateInput.getFullYear()
  5. format = format.replace(/yyyy/, year)
  6. format = format.replace(/MM/,month)
  7. format = format.replace(/dd/,day)
  8. return format
  9. }

2. 实现字符串的repeat方法

输入字符串s,以及其重复的次数,输出重复的结果,例如输入abc,2,输出abcabc。

  1. function repeat(s, n) {
  2. return (new Array(n + 1)).join(s);
  3. }

递归:

  1. function repeat(s, n) {
  2. return (n > 0) ? s.concat(repeat(s, --n)) : "";
  3. }

3. 实现字符串翻转

在字符串的原型链上添加一个方法,实现字符串翻转

  1. String.prototype._reverse = function(a){
  2. return a.split("").reverse().join("");
  3. }
  4. var obj = new String();
  5. var res = obj._reverse ('hello');
  6. console.log(res); // olleh

需要注意的是,必须通过实例化对象之后再去调用定义的方法,不然找不到该方法。

4. 将数字每千分位用逗号隔开

数字有小数版本:

  1. let format = n => {
  2. let num = n.toString() // 转成字符串
  3. let decimals = ''
  4. // 判断是否有小数
  5. num.indexOf('.') > -1 ? decimals = num.split('.')[1] : decimals
  6. let len = num.length
  7. if (len <= 3) {
  8. return num
  9. } else {
  10. let temp = ''
  11. let remainder = len % 3
  12. decimals ? temp = '.' + decimals : temp
  13. if (remainder > 0) { // 不是3的整数倍
  14. return num.slice(0, remainder) + ',' + num.slice(remainder, len).match(/\d{3}/g).join(',') + temp
  15. } else { // 是3的整数倍
  16. return num.slice(0, len).match(/\d{3}/g).join(',') + temp
  17. }
  18. }
  19. }
  20. format(12323.33) // '12,323.33'

数字无小数版本:

  1. let format = n => {
  2. let num = n.toString()
  3. let len = num.length
  4. if (len <= 3) {
  5. return num
  6. } else {
  7. let remainder = len % 3
  8. if (remainder > 0) { // 不是3的整数倍
  9. return num.slice(0, remainder) + ',' + num.slice(remainder, len).match(/\d{3}/g).join(',')
  10. } else { // 是3的整数倍
  11. return num.slice(0, len).match(/\d{3}/g).join(',')
  12. }
  13. }
  14. }
  15. format(1232323) // '1,232,323'

5. 实现非负大整数相加和相乘

JavaScript对数值有范围的限制,限制如下:

  1. Number.MAX_VALUE // 1.7976931348623157e+308
  2. Number.MAX_SAFE_INTEGER // 9007199254740991
  3. Number.MIN_VALUE // 5e-324
  4. Number.MIN_SAFE_INTEGER // -9007199254740991

(1)大数相加

如果想要对一个超大的整数(> Number.MAX_SAFE_INTEGER)进行加法运算,但是又想输出一般形式,那么使用 + 是无法达到的,一旦数字超过 Number.MAX_SAFE_INTEGER 数字会被立即转换为科学计数法,并且数字精度相比以前将会有误差。

实现一个算法进行大数的相加:

  1. function sumBigNumber(a, b) {
  2. let res = '';
  3. let temp = 0;
  4. a = a.split('');
  5. b = b.split('');
  6. while (a.length || b.length || temp) {
  7. temp += ~~a.pop() + ~~b.pop();
  8. res = (temp % 10) + res;
  9. temp = temp > 9
  10. }
  11. return res.replace(/^0+/, '');
  12. }

其主要的思路如下:

  • 首先用字符串的方式来保存大数,这样数字在数学表示上就不会发生变化
  • 初始化res,temp来保存中间的计算结果,并将两个字符串转化为数组,以便进行每一位的加法运算
  • 将两个数组的对应的位进行相加,两个数相加的结果可能大于10,所以可能要仅为,对10进行取余操作,将结果保存在当前位
  • 判断当前位是否大于9,也就是是否会进位,若是则将temp赋值为true,因为在加法运算中,true会自动隐式转化为1,以便于下一次相加
  • 重复上述操作,直至计算结束

    (2)大数相乘

    1. function multiplyBigNum(num1, num2) {
    2. //判断输入是不是数字
    3. if (isNaN(num1) || isNaN(num2)) return "";
    4. num1 = num1 + ""
    5. num2 = num2 + ""
    6. let len1 = num1.length,
    7. len2 = num2.length;
    8. let pos = [];
    9. //j放外面,先固定被乘数的一位,分别去乘乘数的每一位,更符合竖式演算法
    10. for (let j = len2 - 1; j >= 0; j--) {
    11. for (let i = len1 - 1; i >= 0; i--) {
    12. //两个个位数相乘,最多产生两位数,index1代表十位,index2代表个位
    13. let index1 = i + j,
    14. index2 = i + j + 1;
    15. //两个个位数乘积加上当前位置个位已累积的数字,会产生进位,比如08 + 7 = 15,产生了进位1
    16. let mul = num1[i] * num2[j] + (pos[index2] || 0);
    17. //mul包含新计算的十位,加上原有的十位就是最新的十位
    18. pos[index1] = Math.floor(mul / 10) + (pos[index1] || 0);
    19. //mul的个位就是最新的个位
    20. pos[index2] = mul % 10;
    21. }
    22. }
    23. //去掉前置0
    24. let result = pos.join("").replace(/^0+/, "");
    25. return result - 0 || '0';
    26. }

    6. 实现类数组转化为数组

    类数组转换为数组的方法有这样几种:

  • 通过 call 调用数组的 slice 方法来实现转换

    1. Array.prototype.slice.call(arrayLike);
  • 通过 call 调用数组的 splice 方法来实现转换

    1. Array.prototype.splice.call(arrayLike, 0);
  • 通过 apply 调用数组的 concat 方法来实现转换

    1. Array.prototype.concat.apply([], arrayLike);
  • 通过 Array.from 方法来实现转换

    1. Array.from(arrayLike);

    7. 将js对象转化为树形结构

    1. // 转换前:
    2. source = [{
    3. id: 1,
    4. pid: 0,
    5. name: 'body'
    6. }, {
    7. id: 2,
    8. pid: 1,
    9. name: 'title'
    10. }, {
    11. id: 3,
    12. pid: 2,
    13. name: 'div'
    14. }]
    15. // 转换为:
    16. tree = [{
    17. id: 1,
    18. pid: 0,
    19. name: 'body',
    20. children: [{
    21. id: 2,
    22. pid: 1,
    23. name: 'title',
    24. children: [{
    25. id: 3,
    26. pid: 1,
    27. name: 'div'
    28. }]
    29. }
    30. }]
    1. function jsonToTree(data) {
    2. // 初始化结果数组,并判断输入数据的格式
    3. let result = []
    4. if(!Array.isArray(data)) {
    5. return result
    6. }
    7. // 使用map,将当前对象的id与当前对象对应存储起来
    8. let map = {};
    9. data.forEach(item => {
    10. map[item.id] = item;
    11. });
    12. //
    13. data.forEach(item => {
    14. let parent = map[item.pid];
    15. if(parent) {
    16. (parent.children || (parent.children = [])).push(item);
    17. } else {
    18. result.push(item);
    19. }
    20. });
    21. return result;
    22. }

    8. 解析 URL Params 为对象

    1. let url = 'http://www.domain.com/?user=anonymous&id=123&id=456&city=%E5%8C%97%E4%BA%AC&enabled';
    2. parseParam(url)
    3. /* 结果
    4. { user: 'anonymous',
    5. id: [ 123, 456 ], // 重复出现的 key 要组装成数组,能被转成数字的就转成数字类型
    6. city: '北京', // 中文需解码
    7. enabled: true, // 未指定值得 key 约定为 true
    8. }
    9. */
    1. function parseParam(url) {
    2. const paramsStr = /.+\?(.+)$/.exec(url)[1]; // 将 ? 后面的字符串取出来
    3. const paramsArr = paramsStr.split('&'); // 将字符串以 & 分割后存到数组中
    4. let paramsObj = {};
    5. // 将 params 存到对象中
    6. paramsArr.forEach(param => {
    7. if (/=/.test(param)) { // 处理有 value 的参数
    8. let [key, val] = param.split('='); // 分割 key 和 value
    9. val = decodeURIComponent(val); // 解码
    10. val = /^\d+$/.test(val) ? parseFloat(val) : val; // 判断是否转为数字
    11. if (paramsObj.hasOwnProperty(key)) { // 如果对象有 key,则添加一个值
    12. paramsObj[key] = [].concat(paramsObj[key], val);
    13. } else { // 如果对象没有这个 key,创建 key 并设置值
    14. paramsObj[key] = val;
    15. }
    16. } else { // 处理没有 value 的参数
    17. paramsObj[param] = true;
    18. }
    19. })
    20. return paramsObj;
    21. }