一名【合格】前端工程师的自检清单之js语法和API

Author Avatar
w4ctech 7月26日
  • 在其它设备中阅读本文章

最后更新于2019年07月26日; 如遇到问题,请留言及时通知站长

  1. 理解ECMAScriptJavaScript的关系

    • 不管那一种语言的诞生,都会被追本溯源。其实ECMAScriptJavaScript没有什么区别,如果细说的话,ECMA是一种规范,JavaScript是一种实现,这与他们的发展历史有关。
  2. 熟练运用ES5ES6语法规范

    • 相对之前的语法,ES5新加了:

      1. 严格模式:用‘use strict‘声明严格模式。
      2. Array方法:增加了everysomeforEachfilter indexOflastIndexOfisArraymapreducereduceRight方法。

        • every :

          1. every 方法用于检测数组中的元素是否满足指定条件 , 在callback中接受三个参数 :(element, index, array) 即:元素值,元素的索引,原数组 every 方法,检测到数组中的元素都符合条件,才返回true, 否则只要有一项不符合条件,则返回false

            var arrayTest
            function isBigEnough(element, index, array) {
              return (element >= 10);
            }
            arrayTest = [17, 5, 8, 130, 44].every(isBigEnough);
            // false
            arrayTest = [17, 15, 18, 130, 44].every(isBigEnough);
            // true
        • some :

          1. some 方法用于检测数组中的元素是否满足指定条件, 在callback中接受三个参数 :(element, index, array) 即:元素值,元素的索引,原数组。some 方法会对数组中的元素依次检测,若有一个元素满足,就返回true,不再检测,如果没有符合条件的元素,就返回false
          2. 空数组上的任何条件,some方法返回false

            var arrayTest
            function isBigEnough(element, index, array) {
              return (element >= 10);
            }
            arrayTest = [2, 5, 8, 1, 4].some(isBigEnough);
            // false
            arrayTest = [12, 5, 8, 1, 4].some(isBigEnough);
            // true
        • forEach :

          1. forEach 方法常用于循环遍历数组。 在callback中接受三个参数 :(element, index, array) 即:元素值,元素的索引。

            var arr = [ 11, 22, 33 ,44,55];
            arr.forEach(function (element, index, array) {
                console.log(element, index, array);
            });
        • filter :
        • indexOf :
        • lastIndexOf :
        • isArray :
        • map :
        • reduce :
        • reduceRight :
      3. Object方法Object.getPrototypeOfObject.createObject.getOwnPropertyNamesObject.definePropertyObject.getOwnPropertyDescriptorObject.definePropertiesObject.keysObject.preventExtensions / Object.isExtensibleObject.seal / Object.isSealedObject.freeze / Object.isFrozen
    • 还有一些其他方法 Function.prototype.bindString.prototype.trimDate.now等等。
    • 关于ES6

      1. 解构赋值、includes()方法、Array.from()Array.of()for..of...等等。对于ES6不兼容的浏览器可以用Babel转码。
  3. 掌握JavaScript提供的全局对象(例如DateMath)、全局函数(例如decodeURIisNaN)、全局属性(例如Infinity、undefined

    • JS 的全局对象:有ArrayBooleanDateMathNumberStringRegExpFunctionEvent
    • 其中ArrayBooleanNumberDateStringRegExpFunction都是可以通过new来创建对象;而Math可以直接当作对象使用;Event是事件对象,它存在与每个事件函数中。
    • 全局函数:全局函数是内建函数,可以直接调用;

      1. decodeURI()encodeURI() 函数编码过的 URI 进行解码。。
      2. encodeURI():把字符串编码为URI
      3. escape():对字符串进行编码,这样就可以在所有的计算机上读取该字符串。
      4. unescape():对由 escape() 编码的字符串进行解码。
      5. String():把对象的值转换为字符串。
      6. Number():把对象的值转换为数字。
      7. parseFloat():解析一个字符串并返回一个浮点数。
      8. parseInt():解析一个字符串并返回一个整数。
      9. isNaN():检查某个值是否是数字。
      10. isFinite():检查某个值是否为有穷大的数。
      11. getClass():返回一个 JavaObjectJavaClass
      12. eval():计算 JavaScript 字符串,并把它作为脚本代码来执行。
      13. decodeURIComponent():解码一个编码的 URI 组件。
      14. encodeURIComponent():把字符串编码为 URI 组件。
    • 全局属性:

      1. Infinity: 代表正的无穷大的数值。
      2. NaN:指示某个值是不是数值。
      3. undefined: 指未定义的值。
    • 对于ES6不兼容的浏览器可以用Babel转码。
  4. mapreducefilter 等高阶函数

    • map方法: 方法按照原始数组元素顺序依次处理元素。返回一个新数组。参数有两个,第一个未回调函数,函数接受三个参数currentValue( 当前元素的值)、index( 当前元素的索引)、array( 当前元素的数组对象);map的第二个参数可以作为一个对象,在第一个参数中通过this获取,如果省略或传入nullundefined,那么回调函数中的this作为全局对象。

      //js原生实现map方法
      Array.prototype.newMap = function (callback, context) {
          const arr = [];
          if (typeof callback === "function") {
            for (var k = 0, length = this.length; k < length; k++) {
                  const fn = callback.call(context, this[k], k, this);
                  if (fn) {
                      arr.push(fn);
                }
              }
          }
          if (!arr.length) return this;//无值,返回原数组
          return arr;
    • filter方法:检测数值元素,并返回符合条件所有元素的数组。返回一个新数组。如果没有符合条件的元素则返回空数组。参数如同map
它的实现可以参考上述map的实现。

- `reduce`方法:接受哟个函数作为累加器,最终返回的是一个数值,它与上述的区别除了定义上,就是参数的区别;`reduce`第一个参数是回调函数,第二个是一个初始值。回调函数中的参数有四个,第一个参数是上一次的计算结果,剩下的三个参数同`map/filter`回调中参数一样。

- `reduce`还有一些高阶用法:计算数组的中元素出现的次数、数组去重、对象属性求和等等;

  ```javascript
    //js原生实现reduce方法
    Array.prototype.reduce = function (callback, context) {
        if (this && this.length) {
          var initVal = context;
          if (typeof callback === "function") {
            for (var k = 0, length = this.length; k < length; k++) {
              initVal = callback.call(initVal, initVal, this[k], k, this);
            }
          }
          if (!initVal) return this;
          return initVal;
      }
    }
  1. setInterval需要注意的点,使用settimeout实现setInterval

    • setTimeout():在指定的毫秒数后调用函数或计算表达式,只执行一次。
    • setInterval():按照指定的周期(以毫秒计)来调用函数或计算表达式。方法会不停地调用函数,直到 clearInterval() 被调用或窗口被关闭。

        function mySetInterval(fn, millisec,count){
          function interval(){
            if(typeof count===‘undefined’||count-->0){
              setTimeout(interval, millisec);
              try{
                fn()
              }catch(e){
                count = 0;
                throw e.toString();
              }
            }
          }
          setTimeout(interval, millisec)
  2. JavaScript提供的正则表达式API、可以使用正则表达式(邮箱校验、URL解析、去重等)解决常见问题

    • RegExp对象用于存储检索模式。可以通过new来创建实例。

      1. 有 3 个方法:

        • test(): 检索字符串中的指定值。返回值是 truefalse
        • exec():检索字符串中的指定值。返回值是被找到的值。如果没有发现匹配,则返回 null`。
        • compile(): 方法用于改变 RegExp
      2. 支持正则表达式的 String对象的方法:

        • search: 检索与正则表达式相匹配的值。
        • match: 找到一个或多个正则表达式的匹配。
        • replace: 替换与正则表达式匹配的子串。
        • split: 把字符串分割为字符串数组。
      3. 常见的功能:

        • 邮箱校验:^w+[-+.]w+)@w+([-.]w+).w+([-.]w+)*$ 。
        • url 解析

          function parseUrl(url) {
              var parse_url = /^(?:([A-Za-z]+):)?(\/{0,3})([0-9.\-A-Za-z]+)(?::(\d+))?(?:\/([^?#]*))?(?:\?([^#]*))?(?:#(.*))?$/;
              var result = parse_url.exec(url);
              var names = ['url', 'scheme', 'slash', 'host', 'port', 'path', 'query', 'hash'];
              var O = {};
              for (var i = 0, len = names.length; i < len; i += 1) {
                O[names[i]] = result[i]
              }
              return O
            }
          parseUrl('http://zw.zftec.gov.cn:8080/home/details/tzggDetails.htm?id=746212&catalogid=7&page_encoding=UTF-8#209')
          {
              hash: "209"
              host: "zw.zftec.gov.cn"
              path: "home/details/tzggDetails.htm"
              port: "8080"
              query: "id=746212&catalogid=7&page_encoding=UTF-8"
              scheme: "http"
              slash: "//"
              url: "http://zw.zftec.gov.cn:8080/home/details/tzggDetails.htm?id=746212&catalogid=7&page_encoding=UTF-8#209"
          }
          -  字符串去重
          function unique(str) {
              if (typeof str === 'string') {
                var sttr = str.split('').sort().join('').replace(/(.)(\1)+/g, '$1');
                return sttr;
              }
            }
          
          • 校验数字的表达式

            1. 数字:^[0-9]*$
            2. n位的数字:^\d{n}$
            3. 至少n位的数字:^\d{n,}$
            4. m-n位的数字:^\d{m,n}$
            5. 零和非零开头的数字:^(0|[1-9][0-9]*)$
            6. 非零开头的最多带两位小数的数字:^([1-9][0-9]*)+(.[0-9]{1,2})?$
            7. 带1-2位小数的正数或负数:^(\-)?\d+(\.\d{1,2})?$
            8. 正数、负数、和小数:^(\-|\+)?\d+(\.\d+)?$
              10.有1~3位小数的正实数:^[0-9]+(.[0-9]{1,3})?$
              11. 非零的正整数:^[1-9]\d*$ 或 ^([1-9][0-9]*){1,3}$ 或 ^\+?[1-9][0-9]*$
              12. 非零的负整数:^\-[1-9][]0-9"*$ 或 ^-[1-9]\d*$
              13. 非负整数:^\d+$ 或 ^[1-9]\d*|0$
              14. 非正整数:^-[1-9]\d*|0$ 或 ^((-\d+)|(0+))$
              15. 非负浮点数:^\d+(\.\d+)?$ 或 ^[1-9]\d*\.\d*|0\.\d*[1-9]\d*|0?\.0+|0$
              16. 非正浮点数:^((-\d+(\.\d+)?)|(0+(\.0+)?))$ 或 ^(-([1-9]\d*\.\d*|0\.\d*[1-9]\d*))|0?\.0+|0$
              17. 正浮点数:^[1-9]\d*\.\d*|0\.\d*[1-9]\d*$ 或 ^(([0-9]+\.[0-9]*[1-9][0-9]*)|([0-9]*[1-9][0-9]*\.[0-9]+)|([0-9]*[1-9][0-9]*))$
              18. 负浮点数:^-([1-9]\d*\.\d*|0\.\d*[1-9]\d*)$ 或 ^(-(([0-9]+\.[0-9]*[1-9][0-9]*)|([0-9]*[1-9][0-9]*\.[0-9]+)|([0-9]*[1-9][0-9]*)))$
              19. 浮点数:^(-?\d+)(\.\d+)?$ 或 ^-?([1-9]\d*\.\d*|0\.\d*[1-9]\d*|0?\.0+|0)$

        -  校验字符的表达式
              ```javascript
              1. 汉字:^[\u4e00-\u9fa5]{0,}$
              2. 英文和数字:^[A-Za-z0-9]+$ 或 ^[A-Za-z0-9]{4,40}$
              3. 长度为3-20的所有字符:^.{3,20}$
              4. 由26个英文字母组成的字符串:^[A-Za-z]+$
              5. 由26个大写英文字母组成的字符串:^[A-Z]+$
              6. 由26个小写英文字母组成的字符串:^[a-z]+$
              7. 由数字和26个英文字母组成的字符串:^[A-Za-z0-9]+$
              8. 由数字、26个英文字母或者下划线组成的字符串:^\w+$ 或 ^\w{3,20}$
              9. 中文、英文、数字包括下划线:^[\u4E00-\u9FA5A-Za-z0-9_]+$
              10. 中文、英文、数字但不包括下划线等符号:^[\u4E00-\u9FA5A-Za-z0-9]+$ 或 ^[\u4E00-\u9FA5A-Za-z0-9]{2,20}$
              11. 可以输入含有^%&',;=?$\"等字符:[^%&',;=?$\x22]+
              12. 禁止输入含有~的字符:[^~\x22]+

        -  特殊需求表达式**
              ```javascript
              1. Email地址:^\w+([-+.]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*$

              2. 域名:[a-zA-Z0-9][-a-zA-Z0-9]{0,62}(/.[a-zA-Z0-9][-a-zA-Z0-9]{0,62})+/.?

              3. InternetURL:[a-zA-z]+://[^\s]* 或 ^http://([\w-]+\.)+[\w-]+(/[\w-./?%&=]*)?$

              4. 手机号码:^(13[0-9]|14[0-9]|15[0-9]|16[0-9]|17[0-9]|18[0-9]|19[0-9])\d{8}$ (由于工信部放号段不定时,所以建议使用泛解析 ^([1][3,4,5,6,7,8,9])\d{9}$)

              5. 电话号码("XXX-XXXXXXX"、"XXXX-XXXXXXXX"、"XXX-XXXXXXX"、"XXX-XXXXXXXX"、"XXXXXXX"和"XXXXXXXX):^(\(\d{3,4}-)|\d{3.4}-)?\d{7,8}$ 

              6. 国内电话号码(0511-4405222、021-87888822):\d{3}-\d{8}|\d{4}-\d{7} 

              7. 18位身份证号码(数字、字母x结尾):^((\d{18})|([0-9x]{18})|([0-9X]{18}))$

              8. 帐号是否合法(字母开头,允许5-16字节,允许字母数字下划线):^[a-zA-Z][a-zA-Z0-9_]{4,15}$

              9. 密码(以字母开头,长度在6~18之间,只能包含字母、数字和下划线):^[a-zA-Z]\w{5,17}$

              10. 强密码(必须包含大小写字母和数字的组合,不能使用特殊字符,长度在8-10之间):^(?=.*\d)(?=.*[a-z])(?=.*[A-Z]).{8,10}$  

              11. 日期格式:^\d{4}-\d{1,2}-\d{1,2}

              12. 一年的12个月(01~09和1~12):^(0?[1-9]|1[0-2])$

              13. 一个月的31天(01~09和1~31):^((0?[1-9])|((1|2)[0-9])|30|31)$ 

              14 钱的输入格式:

                14-1.有四种钱的表示形式我们可以接受:"10000.00" 和 "10,000.00", 和没有 "分" 的 "10000" 和 "10,000":^[1-9][0-9]*$ 

                14-2.这表示任意一个不以0开头的数字,但是,这也意味着一个字符"0"不通过,所以我们采用下面的形式:^(0|[1-9][0-9]*)$ 

                14-3.一个0或者一个不以0开头的数字.我们还可以允许开头有一个负号:^(0|-?[1-9][0-9]*)$ 

                14-4.这表示一个0或者一个可能为负的开头不为0的数字.让用户以0开头好了.把负号的也去掉,因为钱总不能是负的吧.下面我们要加的是说明可能的小数部分:^[0-9]+(.[0-9]+)?$ 

                14-5.必须说明的是,小数点后面至少应该有1位数,所以"10."是不通过的,但是 "10" 和 "10.2" 是通过的:^[0-9]+(.[0-9]{2})?$ 

                14-6.这样我们规定小数点后面必须有两位,如果你认为太苛刻了,可以这样:^[0-9]+(.[0-9]{1,2})?$ 

                14-7.这样就允许用户只写一位小数.下面我们该考虑数字中的逗号了,我们可以这样:^[0-9]{1,3}(,[0-9]{3})*(.[0-9]{1,2})?$ 

                14-8.1到3个数字,后面跟着任意个 逗号+3个数字,逗号成为可选,而不是必须:^([0-9]+|[0-9]{1,3}(,[0-9]{3})*)(.[0-9]{1,2})?$ 
                备注:这就是最终结果了,别忘了"+"可以用"*"替代如果你觉得空字符串也可以接受的话(奇怪,为什么?)最后,别忘了在用函数时去掉去掉那个反斜杠,一般的错误都在这里

              15. xml文件:^([a-zA-Z]+-?)+[a-zA-Z0-9]+\\.[x|X][m|M][l|L]$

              16. 中文字符的正则表达式:[\u4e00-\u9fa5]

              17. 双字节字符:[^\x00-\xff]    (包括汉字在内,可以用来计算字符串的长度(一个双字节字符长度计2,ASCII字符计1))

              18. 空白行的正则表达式:\n\s*\r    (可以用来删除空白行)

              19. HTML标记的正则表达式:<(\S*?)[^>]*>.*?</\1>|<.*? />    (网上流传的版本太糟糕,上面这个也仅仅能部分,对于复杂的嵌套标记依旧无能为力)

              20. 首尾空白字符的正则表达式:^\s*|\s*$或(^\s*)|(\s*$)    (可以用来删除行首行尾的空白字符(包括空格、制表符、换页符等等),非常有用的表达式)

              21. 腾讯QQ号:[1-9][0-9]{4,}    (腾讯QQ号从10000开始)

              22. 中国邮政编码:[1-9]\d{5}(?!\d)    (中国邮政编码为6位数字)

              23. IP地址:\d+\.\d+\.\d+\.\d+    (提取IP地址时有用)

              24. IP地址:((?:(?:25[0-5]|2[0-4]\\d|[01]?\\d?\\d)\\.){3}(?:25[0-5]|2[0-4]\\d|[01]?\\d?\\d))


  1. JavaScript异常处理的方式,统一的异常处理方案

    • js中最常用用来处理异常的是try..catch语句:

      1. 把有可能出的问题的代码放在try 语句中。try语句中可以理论上可以写任何的代码,只要有一行代码出现问题,整个程序的执行流程就会立即跳到catch语句中执行。
      2. 一旦try中有一行代码发生异常,则这行出错代码的后面的try中的其他语句都不会再执行。可以通过finally语句来执行必须执行的代码。
      3. 在执行catch中的代码之前,js 引擎会首先根据错误类型自动创建一个错误,并通过catch后面的参数传递到catch中。不同的浏览器创建的error对象不一样,但是同创他们都包含一个message属性,值是这个错误的一些信息。catch中的代码执行完毕之后,会继续执行后面的代码,程序不会停止下来。
    • 第二种方式是通过throw主动抛出异常:

      1. thow后面就是我们要抛出的异常对象。在以前的时候都是出现错误的时候浏览器抛出异常对象,只是现在是我们自己主动抛出的异常对象。
      2. 只要有异常对象抛出,不管是浏览器抛出的,还是代码主动抛出,都会让程序停止执行。如果想让程序继续执行,则有也可以用try…catch来捕获。
      3. 每一个错误类型都可以传入一个参数,表示实际的错误信息。
    我们可以在适当的时候抛出任何我们想抛出的异常类型。
   `js`提供来`Error`内置错误对象,我们也可以通过继承来自定义错误对象。

- `js`中的错误类型分类:

    1. **`SyntaxError`**:解析代码时发生的语法错误,比如括号或逗号等等。
    2. ***`ReferenceError`**:`ReferenceError`是引用一个不存在的变量时发生的错误。
    3. **`RangeError`**:`RangeError`是当一个值超出有效范围时发生的错误。主要有几种情况,一是数组长度为负数,二是`Number`对象的方法参数超出范围,以及函数堆栈超过最大值。
    4. **`TypeError`**:`TypeError`是变量或参数不是预期类型时发生的错误。比如,对字符串、布尔值、数值等原始类型的值使用`new`命令,就会抛出这种错误,因为`new`命令的参数应该是一个构造函数。
    5. **`URIError`**:`URIError`是URI相关函数的参数不正确时抛出的错误,主要涉及`encodeURI()`、`decodeURI()`、`encodeURIComponent()`、`decodeURIComponent()`、`escape()`和`unescape()`这六个函数。
    6. **`EvalError`**:`js`中的错误类型`ReferenceError` `eval`函数没有被正确执行时,会抛出EvalError错误。该错误类型已经不再在ES5中出现了,只是为了保证与以前代码兼容,才继续保留。

本文链接:https://w4ctech.cn/frontWeb/api.html
This blog is under a CC BY-NC-SA 3.0 Unported License