csjiabin's blog csjiabin's blog
首页
  • 学习笔记

    • 《JavaScript教程》
    • 《JavaScript高级程序设计》
    • 《ES6 教程》
    • 《Vue》
    • 《React》
    • 《TypeScript 从零实现 axios》
  • 学习笔记

    • 《面向Node.js开发者的Go》
更多
  • 分类
  • 标签
  • 归档
GitHub (opens new window)

csjiabin

前端界的小菜鸟
首页
  • 学习笔记

    • 《JavaScript教程》
    • 《JavaScript高级程序设计》
    • 《ES6 教程》
    • 《Vue》
    • 《React》
    • 《TypeScript 从零实现 axios》
  • 学习笔记

    • 《面向Node.js开发者的Go》
更多
  • 分类
  • 标签
  • 归档
GitHub (opens new window)
  • 学习笔记

    • 《JavaScript教程》笔记
    • 《JavaScript高级程序设计》笔记
    • 《ES6 教程》笔记
    • 《Vue》笔记
    • 《React》笔记
    • 《TypeScript 从零实现 axios》
    • TypeScript笔记
    • 小程序笔记
    • JS设计模式总结笔记
    • 用图标和示例解释Await和Async
    • ES6的Set和Map,以及WeakSet和WeakMap
    • JS中的内存管理
    • JavaScript 易错知识点整理
    • JavaScript有用的代码片段和trick
      • js数组详细操作方法及解析合集
    • 前端
    • 学习笔记
    csjiabin
    2018-08-22
    目录

    JavaScript有用的代码片段和trick

    # 浮点数取整

    const x = 123.4545;
    x >> 0; // 123
    ~~x; // 123
    x | 0; // 123
    Math.floor(x); // 123
    
    1
    2
    3
    4
    5

    注意:前三种方法只适用于 32 个位整数,对于负数的处理上和 Math.floor 是不同的。

    Math.floor(-12.53); // -13
    -12.53 | 0; // -12
    
    1
    2

    # 生成 6 位数字验证码

    // 方法一
    ("000000" + Math.floor(Math.random() * 999999)).slice(-6);
    
    // 方法二
    Math.random().toString().slice(-6);
    
    // 方法三
    Math.random().toFixed(6).slice(-6);
    
    // 方法四
    "" + Math.floor(Math.random() * 999999);
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11

    # 16 进制颜色代码生成

    (function () {
      return (
        "#" + ("00000" + ((Math.random() * 0x1000000) << 0).toString(16)).slice(-6)
      );
    })();
    
    1
    2
    3
    4
    5

    # 驼峰命名转下划线

    "componentMapModelRegistry"
      .match(/^[a-z][a-z0-9]+|[A-Z][a-z0-9]*/g)
      .join("_")
      .toLowerCase(); // component_map_model_registry
    
    1
    2
    3
    4

    # url 查询参数转 json 格式

    // ES6
    const query = (search = "") =>
      ((querystring = "") =>
        ((q) => (
          querystring
            .split("&")
            .forEach((item) =>
              ((kv) => kv[0] && (q[kv[0]] = kv[1]))(item.split("="))
            ),
          q
        ))({}))(search.split("?")[1]);
    
    // 对应ES5实现
    var query = function (search) {
      if (search === void 0) {
        search = "";
      }
      return (function (querystring) {
        if (querystring === void 0) {
          querystring = "";
        }
        return (function (q) {
          return (
            querystring.split("&").forEach(function (item) {
              return (function (kv) {
                return kv[0] && (q[kv[0]] = kv[1]);
              })(item.split("="));
            }),
            q
          );
        })({});
      })(search.split("?")[1]);
    };
    
    query("?key1=value1&key2=value2"); // es6.html:14 {key1: "value1", key2: "value2"}
    
    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
    30
    31
    32
    33
    34
    35

    # 获取 URL 参数

    function getQueryString(key) {
      var reg = new RegExp("(^|&)" + key + "=([^&]*)(&|$)");
      var r = window.location.search.substr(1).match(reg);
      if (!!r) {
        return unescape(r[2]);
      }
      return null;
    }
    
    1
    2
    3
    4
    5
    6
    7
    8

    # n 维数组展开成一维数组

    var foo = [1, [2, 3], ["4", 5, ["6", 7, [8]]], [9], 10];
    
    // 方法一
    // 限制:数组项不能出现`,`,同时数组项全部变成了字符数字
    foo.toString().split(","); // ["1", "2", "3", "4", "5", "6", "7", "8", "9", "10"]
    
    // 方法二
    // 转换后数组项全部变成数字了
    eval("[" + foo + "]"); // [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
    
    // 方法三,使用ES6展开操作符
    // 写法太过麻烦,太过死板
    [1, ...[2, 3], ...["4", 5, ...["6", 7, ...[8]]], ...[9], 10]; // [1, 2, 3, "4", 5, "6", 7, 8, 9, 10]
    
    // 方法四
    JSON.parse(`[${JSON.stringify(foo).replace(/\[|]/g, "")}]`); // [1, 2, 3, "4", 5, "6", 7, 8, 9, 10]
    
    // 方法五
    const flatten = (ary) =>
      ary.reduce((a, b) => a.concat(Array.isArray(b) ? flatten(b) : b), []);
    flatten(foo); // [1, 2, 3, "4", 5, "6", 7, 8, 9, 10]
    
    // 方法六
    function flatten(a) {
      return Array.isArray(a) ? [].concat(...a.map(flatten)) : a;
    }
    flatten(foo); // [1, 2, 3, "4", 5, "6", 7, 8, 9, 10]
    
    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

    注:更多方法请参考《How to flatten nested array in JavaScript?》

    # 日期格式化

    // 方法一
    function format1(x, y) {
      var z = {
        y: x.getFullYear(),
        M: x.getMonth() + 1,
        d: x.getDate(),
        h: x.getHours(),
        m: x.getMinutes(),
        s: x.getSeconds(),
      };
      return y.replace(/(y+|M+|d+|h+|m+|s+)/g, function (v) {
        return ((v.length > 1 ? "0" : "") + eval("z." + v.slice(-1))).slice(
          -(v.length > 2 ? v.length : 2)
        );
      });
    }
    
    format1(new Date(), "yy-M-d h:m:s"); // 17-10-14 22:14:41
    
    // 方法二
    Date.prototype.format = function (fmt) {
      var o = {
        "M+": this.getMonth() + 1, //月份
        "d+": this.getDate(), //日
        "h+": this.getHours(), //小时
        "m+": this.getMinutes(), //分
        "s+": this.getSeconds(), //秒
        "q+": Math.floor((this.getMonth() + 3) / 3), //季度
        S: this.getMilliseconds(), //毫秒
      };
      if (/(y+)/.test(fmt)) {
        fmt = fmt.replace(
          RegExp.$1,
          (this.getFullYear() + "").substr(4 - RegExp.$1.length)
        );
      }
      for (var k in o) {
        if (new RegExp("(" + k + ")").test(fmt)) {
          fmt = fmt.replace(
            RegExp.$1,
            RegExp.$1.length == 1 ? o[k] : ("00" + o[k]).substr(("" + o[k]).length)
          );
        }
      }
      return fmt;
    };
    
    new Date().format("yy-M-d h:m:s"); // 17-10-14 22:18:17
    
    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
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48

    # 统计文字个数

    function wordCount(data) {
      var pattern =
        /[a-zA-Z0-9_\u0392-\u03c9]+|[\u4E00-\u9FFF\u3400-\u4dbf\uf900-\ufaff\u3040-\u309f\uac00-\ud7af]+/g;
      var m = data.match(pattern);
      var count = 0;
      if (m === null) return count;
      for (var i = 0; i < m.length; i++) {
        if (m[i].charCodeAt(0) >= 0x4e00) {
          count += m[i].length;
        } else {
          count += 1;
        }
      }
      return count;
    }
    
    var text =
      "贷款买房,也意味着你能给自己的资产加杠杆,能够撬动更多的钱,来孳生更多的财务性收入。";
    wordCount(text); // 38
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19

    # 特殊字符转义

    function htmlspecialchars(str) {
      var str = str
        .toString()
        .replace(/&/g, "&amp;")
        .replace(/</g, "&lt;")
        .replace(/>/g, "&gt;")
        .replace(/"/g, "&quot;");
      return str;
    }
    
    htmlspecialchars("&jfkds<>"); // "&amp;jfkds&lt;&gt;"
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11

    # 动态插入 js

    function injectScript(src) {
      var s, t;
      s = document.createElement("script");
      s.type = "text/javascript";
      s.async = true;
      s.src = src;
      t = document.getElementsByTagName("script")[0];
      t.parentNode.insertBefore(s, t);
    }
    
    1
    2
    3
    4
    5
    6
    7
    8
    9

    # 格式化数量

    // 方法一
    function formatNum(num, n) {
      if (typeof num == "number") {
        num = String(num.toFixed(n || 0));
        var re = /(-?\d+)(\d{3})/;
        while (re.test(num)) num = num.replace(re, "$1,$2");
        return num;
      }
      return num;
    }
    
    formatNum(2313123, 3); // "2,313,123.000"
    
    // 方法二
    "2313123".replace(/\B(?=(\d{3})+(?!\d))/g, ","); // "2,313,123"
    
    // 方法三
    function formatNum(str) {
      return str
        .split("")
        .reverse()
        .reduce((prev, next, index) => {
          return (index % 3 ? next : next + ",") + prev;
        });
    }
    
    formatNum("2313323"); // "2,313,323"
    
    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

    # 身份证验证

    function chechCHNCardId(sNo) {
      if (!this.regExpTest(sNo, /^[0-9]{17}[X0-9]$/)) {
        return false;
      }
      sNo = sNo.toString();
    
      var a, b, c;
      a =
        parseInt(sNo.substr(0, 1)) * 7 +
        parseInt(sNo.substr(1, 1)) * 9 +
        parseInt(sNo.substr(2, 1)) * 10;
      a =
        a +
        parseInt(sNo.substr(3, 1)) * 5 +
        parseInt(sNo.substr(4, 1)) * 8 +
        parseInt(sNo.substr(5, 1)) * 4;
      a =
        a +
        parseInt(sNo.substr(6, 1)) * 2 +
        parseInt(sNo.substr(7, 1)) * 1 +
        parseInt(sNo.substr(8, 1)) * 6;
      a =
        a +
        parseInt(sNo.substr(9, 1)) * 3 +
        parseInt(sNo.substr(10, 1)) * 7 +
        parseInt(sNo.substr(11, 1)) * 9;
      a =
        a +
        parseInt(sNo.substr(12, 1)) * 10 +
        parseInt(sNo.substr(13, 1)) * 5 +
        parseInt(sNo.substr(14, 1)) * 8;
      a = a + parseInt(sNo.substr(15, 1)) * 4 + parseInt(sNo.substr(16, 1)) * 2;
      b = a % 11;
    
      if (b == 2) {
        c = sNo.substr(17, 1).toUpperCase();
      } else {
        c = parseInt(sNo.substr(17, 1));
      }
    
      switch (b) {
        case 0:
          if (c != 1) {
            return false;
          }
          break;
        case 1:
          if (c != 0) {
            return false;
          }
          break;
        case 2:
          if (c != "X") {
            return false;
          }
          break;
        case 3:
          if (c != 9) {
            return false;
          }
          break;
        case 4:
          if (c != 8) {
            return false;
          }
          break;
        case 5:
          if (c != 7) {
            return false;
          }
          break;
        case 6:
          if (c != 6) {
            return false;
          }
          break;
        case 7:
          if (c != 5) {
            return false;
          }
          break;
        case 8:
          if (c != 4) {
            return false;
          }
          break;
        case 9:
          if (c != 3) {
            return false;
          }
          break;
        case 10:
          if (c != 2) {
            return false;
          }
      }
      return true;
    }
    
    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
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98

    # 测试质数

    function isPrime(n) {
      return !/^.?$|^(..+?)\1+$/.test("1".repeat(n));
    }
    
    1
    2
    3

    # 统计字符串中相同字符出现的次数

    var arr = "abcdaabc";
    
    var info = arr.split("").reduce((p, k) => (p[k]++ || (p[k] = 1), p), {});
    
    console.log(info); //{ a: 3, b: 2, c: 2, d: 1 }
    
    1
    2
    3
    4
    5

    # 使用void 0来解决undefined被污染问题

    undefined = 1;
    !!undefined; // true
    !!void 0; // false
    
    1
    2
    3

    # 单行写一个评级组件

    "★★★★★☆☆☆☆☆".slice(5 - rate, 10 - rate);
    
    1

    # JavaScript 错误处理的方式的正确姿势

    try {
      something;
    } catch (e) {
      window.location.href = "http://stackoverflow.com/search?q=[js]+" + e.message;
    }
    
    1
    2
    3
    4
    5

    # 匿名函数自执行写法

    (function () {})();
    (function () {})();
    [(function () {})()];
    
    ~(function () {})();
    !(function () {})();
    +(function () {})();
    -(function () {})();
    
    delete (function () {})();
    typeof (function () {})();
    void (function () {})();
    new (function () {})();
    new (function () {})();
    
    var f = (function () {})();
    
    1, (function () {})();
    1 ^ (function () {})();
    1 > (function () {})();
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20

    # 两个整数交换数值

    var a = 20,
      b = 30;
    a ^= b;
    b ^= a;
    a ^= b;
    
    a; // 30
    b; // 20
    
    1
    2
    3
    4
    5
    6
    7
    8

    # 数字字符转数字

    var a = "1";
    +a; // 1
    
    1
    2

    # 最短的代码实现数组去重

    [...new Set([1, "1", 2, 1, 1, 3])]; // [1, "1", 2, 3]
    
    1

    # 用最短的代码实现一个长度为 m(6)且值都 n(8)的数组

    Array(6).fill(8); // [8, 8, 8, 8, 8, 8]
    
    1

    # 将 argruments 对象转换成数组

    var argArray = Array.prototype.slice.call(arguments);
    
    // ES6:
    var argArray = Array.from(arguments);
    
    // or
    var argArray = [...arguments];
    
    1
    2
    3
    4
    5
    6
    7

    # 获取日期时间缀

    // 获取指定时间的时间缀
    new Date().getTime();
    new Date().getTime();
    new Date().getTime();
    // 获取当前的时间缀
    Date.now();
    // 日期显示转换为数字
    +new Date();
    
    1
    2
    3
    4
    5
    6
    7
    8

    # 使用~x.indexOf('y')来简化x.indexOf('y') > -

    var str = "hello world";
    if (str.indexOf("lo") > -1) {
      // ...
    }
    
    if (~str.indexOf("lo")) {
      // ...
    }
    
    1
    2
    3
    4
    5
    6
    7
    8

    # parseInt() or Number()

    两者的差别之处在于解析和转换两者之间的理解。

    解析允许字符串中含有非数字字符,解析按从左到右的顺序,如果遇到非数字字符就停止。而转换不允许出现非数字字符,否者会失败并返回 NaN。

    var a = "520";
    var b = "520px";
    
    Number(a); // 520
    parseInt(a); // 520
    
    Number(b); // NaN
    parseInt(b); // 520
    
    1
    2
    3
    4
    5
    6
    7
    8

    parseInt方法第二个参数用于指定转换的基数,ES5 默认为 10 进制。

    parseInt("10", 2); // 2
    parseInt("10", 8); // 8
    parseInt("10", 10); // 10
    parseInt("10", 16); // 16
    
    1
    2
    3
    4

    对于网上parseInt(0.0000008)的结果为什么为 8,原因在于 0.0000008 转换成字符为"8e-7",然后根据parseInt的解析规则自然得到"8"这个结果。

    # +拼接操作,+x or String(x)?

    +运算符可用于数字加法,同时也可以用于字符串拼接。如果+的其中一个操作符是字符串(或者通过 隐式强制转换可以得到字符串),则执行字符串拼接;否者执行数字加法。

    需要注意的时对于数组而言,不能通过valueOf()方法得到简单基本类型值,于是转而调用toString()方法。

    [1, 2] + [3, 4]; // "1,23,4"
    
    1

    对于对象同样会先调用valueOf()方法,然后通过toString()方法返回对象的字符串表示。

    var a = {};
    a + 123; // "[object Object]123"
    
    1
    2

    对于a + ""隐式转换和String(a)显示转换有一个细微的差别:a + ''会对 a 调用valueOf()方法,而String()直接调用toString()方法。大多数情况下我们不会考虑这个问题,除非真遇到。

    var a = {
      valueOf: function () {
        return 42;
      },
      toString: function () {
        return 4;
      },
    };
    
    a + ""; // 42
    String(a); // 4
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11

    # 判断对象的实例

    // 方法一: ES3
    function Person(name, age) {
      if (!(this instanceof Person)) {
        return new Person(name, age);
      }
      this.name = name;
      this.age = age;
    }
    
    // 方法二: ES5
    function Person(name, age) {
      var self = this instanceof Person ? this : Object.create(Person.prototype);
      self.name = name;
      self.age = age;
    
      return self;
    }
    
    // 方法三:ES6
    function Person(name, age) {
      if (!new.target) {
        throw "Peron must called with new";
      }
      this.name = name;
      this.age = age;
    }
    
    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

    # 数据安全类型检查

    // 对象
    function isObject(value) {
      return Object.prototype.toString.call(value).slice(8, -1) === 'Object'';
    }
    
    // 数组
    function isArray(value) {
      return Object.prototype.toString.call(value).slice(8, -1) === 'Array';
    }
    
    // 函数
    function isFunction(value) {
      return Object.prototype.toString.call(value).slice(8, -1) === 'Function';
    }
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14

    # 让数字的字面值看起来像对象

    2.toString(); // Uncaught SyntaxError: Invalid or unexpected token
    
    2..toString(); // 第二个点号可以正常解析
    2 .toString(); // 注意点号前面的空格
    (2).toString(); // 2先被计算
    
    1
    2
    3
    4
    5

    # 对象可计算属性名(仅在 ES6 中)

    var suffix = " name";
    var person = {
      ["first" + suffix]: "Nicholas",
      ["last" + suffix]: "Zakas",
    };
    
    person["first name"]; // "Nicholas"
    person["last name"]; // "Zakas"
    
    1
    2
    3
    4
    5
    6
    7
    8

    # 数字四舍五入

    // v: 值,p: 精度
    function (v, p) {
      p = Math.pow(10, p >>> 31 ? 0 : p | 0)
      v *= p;
      return (v + 0.5 + (v >> 31) | 0) / p
    }
    
    round(123.45353, 2); // 123.45
    
    1
    2
    3
    4
    5
    6
    7
    8

    # 在浏览器中根据 url 下载文件

    function download(url) {
      var isChrome = navigator.userAgent.toLowerCase().indexOf("chrome") > -1;
      var isSafari = navigator.userAgent.toLowerCase().indexOf("safari") > -1;
    
      if (isChrome || isSafari) {
        var link = document.createElement("a");
        link.href = url;
    
        if (link.download !== undefined) {
          var fileName = url.substring(url.lastIndexOf("/") + 1, url.length);
          link.download = fileName;
        }
    
        if (document.createEvent) {
          var e = document.createEvent("MouseEvents");
          e.initEvent("click", true, true);
          link.dispatchEvent(e);
          return true;
        }
      }
    
      if (url.indexOf("?") === -1) {
        url += "?download";
      }
    
      window.open(url, "_self");
      return true;
    }
    
    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

    # 快速生成 UUID

    function uuid() {
      var d = new Date().getTime();
      var uuid = "xxxxxxxxxxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(
        /[xy]/g,
        function (c) {
          var r = (d + Math.random() * 16) % 16 | 0;
          d = Math.floor(d / 16);
          return (c == "x" ? r : (r & 0x3) | 0x8).toString(16);
        }
      );
      return uuid;
    }
    
    uuid(); // "33f7f26656cb-499b-b73e-89a921a59ba6"
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14

    # JavaScript 浮点数精度问题

    function isEqual(n1, n2, epsilon) {
      epsilon = epsilon == undefined ? 10 : epsilon; // 默认精度为10
      return n1.toFixed(epsilon) === n2.toFixed(epsilon);
    }
    
    0.1 + 0.2; // 0.30000000000000004
    isEqual(0.1 + 0.2, 0.3); // true
    
    0.7 + 0.1 + 99.1 + 0.1; // 99.99999999999999
    isEqual(0.7 + 0.1 + 99.1 + 0.1, 100); // true
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10

    # 格式化表单数据

    function formatParam(obj) {
      var query = "",
        name,
        value,
        fullSubName,
        subName,
        subValue,
        innerObj,
        i;
    
      for (name in obj) {
        value = obj[name];
    
        if (value instanceof Array) {
          for (i = 0; i < value.length; ++i) {
            subValue = value[i];
            fullSubName = name + "[" + i + "]";
            innerObj = {};
            innerObj[fullSubName] = subValue;
            query += formatParam(innerObj) + "&";
          }
        } else if (value instanceof Object) {
          for (subName in value) {
            subValue = value[subName];
            fullSubName = name + "[" + subName + "]";
            innerObj = {};
            innerObj[fullSubName] = subValue;
            query += formatParam(innerObj) + "&";
          }
        } else if (value !== undefined && value !== null)
          query += encodeURIComponent(name) + "=" + encodeURIComponent(value) + "&";
      }
      return query.length ? query.substr(0, query.length - 1) : query;
    }
    
    var param = {
      name: "jenemy",
      likes: [0, 1, 3],
      memberCard: [
        { title: "1", id: 1 },
        { title: "2", id: 2 },
      ],
    };
    
    formatParam(param); // "name=12&likes%5B0%5D=0&likes%5B1%5D=1&likes%5B2%5D=3&memberCard%5B0%5D%5Btitle%5D=1&memberCard%5B0%5D%5Bid%5D=1&memberCard%5B1%5D%5Btitle%5D=2&memberCard%5B1%5D%5Bid%5D=2"
    
    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
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45

    # 创建指定长度非空数组

    在 JavaScript 中可以通过new Array(3)的形式创建一个长度为 3 的空数组。在老的 Chrome 中其值为[undefined x 3],在最新的 Chrome 中为[empty x 3],即空单元数组。在老 Chrome 中,相当于显示使用[undefined, undefined, undefined]的方式创建长度为 3 的数组。

    但是,两者在调用map()方法的结果是明显不同的

    var a = new Array(3);
    var b = [undefined, undefined, undefined];
    
    a.map((v, i) => i); // [empty × 3]
    b.map((v, i) => i); // [0, 1, 2]
    
    1
    2
    3
    4
    5

    多数情况我们期望创建的是包含undefined值的指定长度的空数组,可以通过下面这种方法来达到目的:

    var a = Array.apply(null, { length: 3 });
    
    a; // [undefined, undefined, undefined]
    a.map((v, i) => i); // [0, 1, 2]
    
    1
    2
    3
    4

    总之,尽量不要创建和使用空单元数组。

    # debounce 方法

    debounce()方法用来延迟执行函数。

    var debounce = function (func, threshold, execAsap) {
      var timeout;
    
      return function debounced() {
        var obj = this,
          args = arguments;
        function delayed() {
          if (!execAsap) func.apply(obj, args);
          timeout = null;
        }
    
        if (timeout) clearTimeout(timeout);
        else if (execAsap) func.apply(obj, args);
    
        timeout = setTimeout(delayed, threshold || 100);
      };
    };
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17

    # 判断客户端

    var browser = {
      v: (function () {
        var u = navigator.userAgent,
          app = navigator.appVersion,
          p = navigator.platform;
        return {
          trident: u.indexOf("Trident") > -1, //IE内核
          presto: u.indexOf("Presto") > -1, //opera内核
          webKit: u.indexOf("AppleWebKit") > -1, //苹果、谷歌内核
          gecko: u.indexOf("Gecko") > -1 && u.indexOf("KHTML") == -1, //火狐内核
          mobile: !!u.match(/AppleWebKit.*Mobile.*/), //是否为移动终端
          ios: !!u.match(/i[^;]+;( U;)? CPU.+Mac OS X/), //ios终端
          android: u.indexOf("Android") > -1 || u.indexOf("Linux") > -1, //android终端或uc浏览器
          iPhone: u.indexOf("iPhone") > -1, //是否为iPhone或者QQHD浏览器
          iPad: u.indexOf("iPad") > -1, //是否iPad
          weixin: u.indexOf("MicroMessenger") > -1, //是否微信
          webApp: u.indexOf("Safari") == -1, //是否web应该程序,没有头部与底部
          UCB: u.match(/UCBrowser/i) == "UCBrowser",
          QQB: u.match(/MQQBrowser/i) == "MQQBrowser",
          win: p.indexOf("Win") > -1, //判断是否是WIN操作系统
          mac: p.indexOf("Mac") > -1, //判断是否是Mac操作系统
        };
      })(),
    };
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    编辑 (opens new window)
    #js
    上次更新: 2022/09/30, 11:34:22
    JavaScript 易错知识点整理
    js数组详细操作方法及解析合集

    ← JavaScript 易错知识点整理 js数组详细操作方法及解析合集→

    最近更新
    01
    咖啡知识
    10-13
    02
    documentation
    09-29
    03
    benchmarking
    09-29
    更多文章>
    Theme by Vdoing | Copyright © 2018-2022 csjiabin | MIT License
    • 跟随系统
    • 浅色模式
    • 深色模式
    • 阅读模式