*   返回值:

        返回一个迭代器,可用`for`或`Array.from`来遍历

    *   说明:

        1.  对比`reg.exec()`和`str.matchAll()`:

            在 `matchAll` 出现之前,通过在循环中调用 `reg.exec()` 来获取所有匹配项信息(`reg` 需使用 `/g` 标志):

            ```

            const reg = RegExp('foo[a-z]*','g');

            const str = 'table football, foosball';

            let match;

            while ((match = reg.exec(str)) !== null) {

                console.log(`Find: ${match[0]} start: ${match.index} end: ${reg.lastIndex}`);

                // Find: football start: 6 end: 14

                // test.html:93 Find: foosball start: 16 end: 24

            } 

            ```

            如果使用 `matchAll` ,就可以不必使用 while 循环加 exec 方式(且正则表达式需使用 `/g` 标志)。使用 `matchAll` 会得到一个迭代器的返回值,配合 `for...of`, `array spread`, 或者 `Array.from()` 可以更方便实现功能:

            ```

            const reg = RegExp('foo[a-z]*','g');

            const str = 'table football, foosball';

            const match = str.matchAll(reg);

            for (const item of match) {

                console.log(`Find ${item[0]} start: ${item.index} end: ${item.index + item[0].length}`);

                // Find: football start: 6 end: 14

                // test.html:93 Find: foosball start: 16 end: 24

            }

            const arr = Array.from(str.matchAll(reg), m => m[0]);

            console.log(arr); // ["football", "foosball"] 

            ```

        2.  `matchAll`内部做了一个`reg`的复制,所以不像`reg.exec`,`lastIndex`在字符串扫描时不会改变

            ```

            const regexp = RegExp('[a-c]','g');

            regexp.lastIndex = 1;

            const str = 'abc';

            Array.from(str.matchAll(regexp), m => `${regexp.lastIndex} ${m[0]}`);

            // Array [ "1 b", "1 c" ] 

            ```

        3.  `matchAll` 的另外一个亮点是更好地获取捕获组。因为当使用 `match()` 和 `/g` 标志方式获取匹配信息时,捕获组会被忽略:

            ```

            var regexp = /t(e)(st(/d?))/g;

            var str = 'test1test2';

            str.match(regexp);

            // Array ['test1', 'test2'] 

            ```

            使用 `matchAll` 可以通过如下方式获取分组捕获:

            ```

            let array = [...str.matchAll(regexp)];

            array[0];

            // ['test1', 'e', 'st1', '1', index: 0, input: 'test1test2', length: 4]

            array[1];

            // ['test2', 'e', 'st2', '2', index: 5, input: 'test1test2', length: 4] 

            ```

*   `replace`

    *   语法:

        ```

        // reg:一个RegExp对象或者其字面量.该正则所匹配的内容会被第二个参数的返回值替换

        // substr:一个将被newSubstr替换的字符串.仅第一个匹配项会被替换.

        // newSubstr:用于替换掉第一个参数在原字符串中的匹配部分的字符串。该字符串中可以内插一些特殊的变量名。

        // replaceFunction:一个用来创建新子字符串的函数,该函数的返回值将替换掉第一个参数匹配到的结果

        str.replace(reg|substr, newSubstr|replaceFunction) 

        ```

    *   返回值:

        该方法并不改变调用它的字符串本身,而只是返回一个新的替换后的字符串。

    *   第二个参数说明:

        *   `newSubstr`可插入下面的特殊变量名:

            | 变量名 | 代表的值 |

            | --- | --- |

            | `$$` | 插入一个`"$"` |

            | `$&` | 插入匹配的子串 |

            | $/` | 插入当前匹配的子串左边的内容 |

            | `$'` | 插入当前匹配的子串右边的内容 |

            | `$n` | 当第一个参数是`RegExp`对象且包含捕获组,`$n`对应第`n`个捕获组匹配的子串 |

            | `$<name>` | 这里/*`Name`/* 是一个分组名称。如果在正则表达式中并不存在分组(或者没有匹配),这个变量将被处理为空字符串。 |

        *   `replaceFunction`

            第二个参数可以指定为一个函数,函数的返回值作为替换的字符串.注意,每执行一次匹配,该函数就会执行一次(所以当第一个参数是正则表达式,并且设置了全局匹配`g`,那么`replaceFunction`会被多次调用,每次匹配都用被调用),如下,第一个`aa`被替换为0,第二个`aa`被替换为1

            ```

            const str = 'aabbaaccdd';

            const reg = /aa/g;

            let i = 0;

            function fn (match) {

                return i++;

            }

            console.log(str.replace(reg, fn)); // 0bb1ccdd 

            ```

            以下是该函数的参数:

            | 变量名 | 代表的值 |

            | --- | --- |

            | `match` | 匹配的子串(对应于上述的`$&`) |

            | `p1,p2,...` | 对应上述的`&1,&2,...` |

            | `offset` | 匹配到的子字符串在原字符串中的偏移量.(比如,如果原字符串是`abcd`,匹配到的子字符串是`bc`,那么偏移量就是1) |

            | `string` | 被匹配的原字符串 |

            | `NamedCaptureGroup` | 命名捕获组匹配的对象 |

    *   例子:

        1.  下面的例子将会使 `newString` 变成 `'abc - 12345 - #$*%'`:

            ```

            function replacer(match, p1, p2, p3, offset, string) {

              // p1 is nondigits, p2 digits, and p3 non-alphanumerics

              return [p1, p2, p3].join(' - ');

            }

            var newString = 'abc12345#$*%'.replace(/([^/d]*)(/d*)([^/w]*)/, replacer);

            console.log(newString);  // abc - 12345 - #$*% 

            ```

        2.  交换字符串中的两个单词:

            ```

            var re = /(/w+)/s(/w+)/;

            var str = "John Smith";

            var newstr = str.replace(re, "$2, $1");

            // Smith, John

            console.log(newstr); 

            ```

        3.  使用行内函数来修改匹配到的字符:

            ```

            function upperToHyphenLower(match){

                return '-' + match.toLowerCase();

            }

            console.log('borderTop'.replace(/[A-Z]/g, upperToHyphenLower)); // border-top 

            ```

            因为我们想在最终的替换中进一步转变匹配结果(比如这里使用`toLowerCase`方法进行转换),所以我们必须使用一个函数.如果我们不使用一个函数进行匹配,那么`toLowerCase()`方法不会起效.如:

            ```

            var newString = propertyName.replace(/[A-Z]/g, '-' + '$&'.toLowerCase());  // won't work 

            ```

            这是因为 `'$&'.toLowerCase()` 会先被解析成字符串字面量(这会导致相同的’$&’)而不是当作一个模式

*   `search`

    *   语法:

        ```

        str.search(reg) 

        ```

    *   返回值:

        如果匹配成功,则 `search()` 返回正则表达式在字符串中首次匹配项的索引;否则,返回 `-1`。

        事实上,`search`相对于`match`,就像`test`相对于`exec`.当仅仅想知道字符串中是否存在某个`pattern`时,可使用`search`和`test`,而当想获取更多的匹配信息时,可使用`match`和`exec`(会更慢一些).

    *   例子:

        ```

        var str = "hey JudE";

        var re = /[A-Z]/g;

        var re2 = /[.]/g;

        console.log(str.search(re)); // 4

        console.log(str.search(re2)); // -1 

        ```

*   `split`

    *   语法:

        ```

        // separator:分隔符

        // limit:限制返回数组的项数最大值

        str.split([separator[, limit]]); 

        ```

    *   返回值:

        1.  `separator`为字符串,返回`str`以`separator`作为分隔符切割的子字符串的数组;

        2.  `separator`为正则表达式,返回`str`匹配`separator`作为分隔符切割的子字符串的数组;如果分隔符是包含捕获括号的正则表达式,则每次分隔符匹配时,捕获括号的结果(包括任何未定义的结果)将被拼接到输出数组中。

        3.  如果`str`没有找到`separator`或者省略了`separator`.则返回包含`str`的数组;

    *   例子:

        ```

        const str = 'aabbccbbddee';

        console.log(str.split()); // ['aabbccbbddee']

        console.log(str.split('')); // ["a", "a", "b", "b", "c", "c", "b", "b", "d", "d", "e", "e"]

        console.log(str.split('', 4)); // ["a", "a", "b", "b"]

        console.log(str.split(/b+/)); // ["aa", "cc", "ddee"]

        console.log(str.split(/(b+)/)); // ["aa", "bb", "cc", "bb", "ddee"]

        console.log('ca,bc,a,bca,bca,bc'.split(['a','b'])); // ["c", "c,", "c", "c", "c"] 

        ```

[](

)1.2 创建正则表达式

  1. 通过 RegExp 对象的构造函数创建:

    在脚本运行过程中,用构造函数创建的正则表达式会被编译。如果正则表达式将会改变,或者它将会从用户输入等来源中动态地产生,就需要使用构造函数来创建正则表达式。

    
    var 变量名 = new RegExp(/表达式/); 
    
  2. 通过字面量创建

    脚本加载后,正则表达式字面量就会被编译。当正则表达式保持不变时,使用此方法可获得更好的性能。

    
    var 变量名 = /表达式/; 
    

[](

)1.3 特殊字符

[](

)量词符

| 字符 | 用法 |

| :-: | — |

| * | 匹配前一个表达式 0 次或多次.等价于 {0,}

例如,/bo*/ 会匹配"A ghost boooooed"中的 'booooo'"A bird warbled" 中的 'b',但是在 "A goat grunted" 中不会匹配任何内容 |

| + | 匹配前面一个表达式 1 次或者多次.等价于 {1,}

例如,/a+/ 会匹配 "candy" 中的'a'"caaaaaaandy" 中所有的'a',但是在 "cndy"中不会匹配任何内容 |

| ? | 1. 匹配前面一个表达式 0 次或者 1 次.等价于 {0,1}

例如,/e?le?/ 匹配 "angel" 中的 'el'"angle"中的'le' 以及"also'中的 'l';

2. 如果紧跟在任何量词* + ?或者{}的后面,会使量词变得非贪婪(匹配尽量少的字符),和缺省使用的贪婪模式(匹配尽可能多的字符)相反.

如,对"123abc"使用//d+/会匹配"123",而使用//d+?/则只会匹配到""`

3. 还用于先行断言 |

| {n} | n 是一个正整数,匹配了前面一个字符刚好出现了 n 次。

比如, /a{2}/ 不会匹配“candy”中的’a’,但是会匹配“caandy”中所有的 a,以及“caaandy”中的前两个’a’。 |

| {n,} | n是一个正整数,匹配前一个字符至少出现了n次。

例如, /a{2,}/ 匹配 “aa”, “aaaa” 和 “aaaaa” 但是不匹配 “a”。 |

| {n,m} | n 和 m 都是整数。匹配前面的字符至少n次,最多m次。如果 n 或者 m 的值是0, 这个值被忽略。

例如,/a{1, 3}/ 并不匹配“cndy”中的任意字符,匹配“candy”中的a,匹配“caandy”中的前两个a,也匹配“caaaaaaandy”中的前三个a。注意,当匹配”caaaaaaandy“时,匹配的值是“aaa”,即使原始的字符串中有更多的a。 |

[](

)边界符

| 字符 | 用法 |

| :-: | — |

| ^ | 1. 匹配输入的开始,如果多行标志被设置为true,那么也匹配换行符后紧跟的位置.

/^A/ 并不会匹配"an A"中的'A',但是会匹配 "An E"中的'A'

2. 反向字符集合 |

| $ | 匹配输入的结束.如果多行标志被设置为 true,那么也匹配换行符前的位置。

例如,/t$/ 并不会匹配 "eater"中的't',但是会匹配 "eat" 中的't' |

如果 ^ 和 $ 在一起,表示必须是精确匹配

Vue 面试题

1.Vue 双向绑定原理
2.描述下 vue 从初始化页面–修改数据–刷新页面 UI 的过程?
3.你是如何理解 Vue 的响应式系统的?
4.虚拟 DOM 实现原理
5.既然 Vue 通过数据劫持可以精准探测数据变化,为什么还需要虚拟 DOM 进行 diff 检测差异?
6.Vue 中 key 值的作用?
7.Vue 的生命周期
8.Vue 组件间通信有哪些方式?
9.watch、methods 和 computed 的区别?
10.vue 中怎么重置 data?
11.组件中写 name 选项有什么作用?
12.vue-router 有哪些钩子函数?
13.route 和 router 的区别是什么?
14.说一下 Vue 和 React 的认识,做一个简单的对比
15.Vue 的 nextTick 的原理是什么?
16.Vuex 有哪几种属性?
17.vue 首屏加载优化
18.Vue 3.0 有没有过了解?
19.vue-cli 替我们做了哪些工作?
JavaScript,web快速开发框架

CodeChina开源项目:【大厂前端面试题解析+核心总结学习笔记+真实项目实战+最新讲解视频】