فهرست منبع

chore: modify typos

miaoyuxinbaby 7 سال پیش
والد
کامیت
6cc1a0a99f
1فایلهای تغییر یافته به همراه16 افزوده شده و 16 حذف شده
  1. 16 16
      docs/art/82vue-parsing.md

+ 16 - 16
docs/art/82vue-parsing.md

@@ -2878,7 +2878,7 @@ let paren = 0
 
 * 在解析绑定的属性值时,每遇到一个左花括号(`{`),则 `curly` 变量的值就会加一,每遇到一个右花括号(`}`),则 `curly` 变量的值就会减一。
 * 在解析绑定的属性值时,每遇到一个左方括号(`[`),则 `square` 变量的值就会加一,每遇到一个右方括号(`]`),则 `square` 变量的值就会减一。
-* 在解析绑定的属性值时,每遇到一个左圆括号(`(`),则 `paren` 变量的值就会加一,每遇到一个右括号(`)`),则 `paren` 变量的值就会减一。
+* 在解析绑定的属性值时,每遇到一个左圆括号(`(`),则 `paren` 变量的值就会加一,每遇到一个右括号(`)`),则 `paren` 变量的值就会减一。
 
 当 `parseFilters` 函数在解析属性值字符串并遇到一个管道符时,该管道符应不应该作为过滤器的分界线还要看以上三个变量是否为 `0`,如果以上三个变量至少有一个不为 `0`,则说明该管道符存在于花括号或方括号或圆括号之内,这时该管道符是不会被作为过滤器的分界线的,如下:
 
@@ -2915,7 +2915,7 @@ for (i = 0; i < exp.length; i++) {
 }
 ```
 
-可以看到每次循环的开始,都会将上一次读取的字符所对应的 `ASCII` 码赋值给 `prev` 变量,然后再变量 `c` 的值设置为当前读取字符所对应的 `ASCII` 码。所以我们说 `prev` 变量中保存的是上一个字符的 `ASCII` 码。
+可以看到每次循环的开始,都会将上一次读取的字符所对应的 `ASCII` 码赋值给 `prev` 变量,然后再变量 `c` 的值设置为当前读取字符所对应的 `ASCII` 码。所以我们说 `prev` 变量中保存的是上一个字符的 `ASCII` 码。
 
 在这两句代码的下面是一连串的 `if...elseif...else` 语句,如下:
 
@@ -2958,7 +2958,7 @@ if (inSingle) {
 c === 0x27 && prev !== 0x5C
 ```
 
-这个判断条件是什么意思呢?可以看到如上判断条件中有两个十六进制的数字:`0x27` 和 `0x5C`,这两个十六进制的数字实际上就是字符的 `ASCII` 码,其中 `0x27` 为字符单引号(`'`)所对应的 `ASCII` 码,而 `0x5C` 则是字符反斜杠(`\`)所对应的 `ASCII` 码。所以如上判断条件翻译过来就是:当前字符是单引号(`'`),并且当前字符的前一个字符不是反斜杠(`\`),也就是说当前字符(`单引号`)就是字符串的结束。该判断条件的关键在于不仅要当前字符是单引号(`'`),同时前一个字符也一定不能是反斜杠才行,这是因为反斜杠在字符串内具有转的作用。如果判断条件成立,则将 `inSingle` 变量的值设置为 `false`,代表接下来的解析工作已经不处于由单引号所包裹的字符串环境中了。
+这个判断条件是什么意思呢?可以看到如上判断条件中有两个十六进制的数字:`0x27` 和 `0x5C`,这两个十六进制的数字实际上就是字符的 `ASCII` 码,其中 `0x27` 为字符单引号(`'`)所对应的 `ASCII` 码,而 `0x5C` 则是字符反斜杠(`\`)所对应的 `ASCII` 码。所以如上判断条件翻译过来就是:当前字符是单引号(`'`),并且当前字符的前一个字符不是反斜杠(`\`),也就是说当前字符(`单引号`)就是字符串的结束。该判断条件的关键在于不仅要当前字符是单引号(`'`),同时前一个字符也一定不能是反斜杠才行,这是因为反斜杠在字符串内具有转的作用。如果判断条件成立,则将 `inSingle` 变量的值设置为 `false`,代表接下来的解析工作已经不处于由单引号所包裹的字符串环境中了。
 
 再来看下一个 `elseif` 判断分支:
 
@@ -2968,7 +2968,7 @@ else if (inDouble) {
 }
 ```
 
-与单引号的情况类似,该 `elseif` 条件语句检查了变量 `inDouble` 是否为真,如果为真则说明当前字符处于由双引号包裹的字符串中,此时会检查当前字符所对应的 `ASCII` 码是否等于 `0x22`,这里的数字 `0x22` 就是字符双引号(`"`)所对应的 `ASCII` 码。所以如上判断语句成立则等价于:当前字符是双引号,并且前一个字符不是转字符(`\`)。这说明当前字符(`双引号`)就应该是字符串的结束,此时会将变量 `inDouble` 的值设置为 `false`,代表接下来的解析工作已经不处于由双引号所包裹的字符串环境中了。
+与单引号的情况类似,该 `elseif` 条件语句检查了变量 `inDouble` 是否为真,如果为真则说明当前字符处于由双引号包裹的字符串中,此时会检查当前字符所对应的 `ASCII` 码是否等于 `0x22`,这里的数字 `0x22` 就是字符双引号(`"`)所对应的 `ASCII` 码。所以如上判断语句成立则等价于:当前字符是双引号,并且前一个字符不是转字符(`\`)。这说明当前字符(`双引号`)就应该是字符串的结束,此时会将变量 `inDouble` 的值设置为 `false`,代表接下来的解析工作已经不处于由双引号所包裹的字符串环境中了。
 
 再接着是如下判断分支,它同时是一个 `elseif` 语句块:
 
@@ -2978,7 +2978,7 @@ else if (inTemplateString) {
 }
 ```
 
-这个判断语句与前两个判断语句类似,如果该 `elseif` 语句的条件成立,则说明当前字符处在模板字符串中,此时会继续检测当前字符所对应的 `ASCII` 码是否等于 `0x60`,这里的数字 `0x60` 就是字符 `` ` `` 所对应的 `ASCII` 码。所以如上判断语句成立则等价于:当前字符是 `` ` ``,并且前一个字符不是转字符(`\`)。这说明当前字符(`` ` ``)就应该是模板字符串的结束,此时会将变量 `inTemplateString` 的值设置为 `false`,代表接下来的解析工作已经不处于模板字符串环境中了。
+这个判断语句与前两个判断语句类似,如果该 `elseif` 语句的条件成立,则说明当前字符处在模板字符串中,此时会继续检测当前字符所对应的 `ASCII` 码是否等于 `0x60`,这里的数字 `0x60` 就是字符 `` ` `` 所对应的 `ASCII` 码。所以如上判断语句成立则等价于:当前字符是 `` ` ``,并且前一个字符不是转字符(`\`)。这说明当前字符(`` ` ``)就应该是模板字符串的结束,此时会将变量 `inTemplateString` 的值设置为 `false`,代表接下来的解析工作已经不处于模板字符串环境中了。
 
 再来看下一个 `elseif` 条件语句块:
 
@@ -2988,7 +2988,7 @@ else if (inRegex) {
 }
 ```
 
-如果该 `elseif` 语句的条件成立,则说明当前字符处在正则表达式中,此时会继续检测当前字符所对应的 `ASCII` 码是否等于 `0x2f`,这里的数字 `0x2f` 就是字符 `/` 所对应的 `ASCII` 码。所以如上判断语句成立则等价于:当前字符是 `/`,并且前一个字符不是转字符(`\`)。这说明当前字符(`/`)就应该是正则表达式的结束,此时会将变量 `inRegex` 的值设置为 `false`,代表接下来的解析工作已经不处于正则表达式的环境中了。
+如果该 `elseif` 语句的条件成立,则说明当前字符处在正则表达式中,此时会继续检测当前字符所对应的 `ASCII` 码是否等于 `0x2f`,这里的数字 `0x2f` 就是字符 `/` 所对应的 `ASCII` 码。所以如上判断语句成立则等价于:当前字符是 `/`,并且前一个字符不是转字符(`\`)。这说明当前字符(`/`)就应该是正则表达式的结束,此时会将变量 `inRegex` 的值设置为 `false`,代表接下来的解析工作已经不处于正则表达式的环境中了。
 
 再往下的一个 `elseif` 条件语句的判断条件稍微复杂一些,如下:
 
@@ -3054,7 +3054,7 @@ if (inSingle) {
 }
 ```
 
-但是很显然字符 `i` 所对应的 `ASCII` 码不等于 `0x27`,所以这等于什么都没做,直接跳过解析下一个字符。下一个字符是 `d`,它的情况与字符 `i` 一样,也会被跳过。知道遇到最后一个字符 `'`,该字符同样是单引号,所以此时会将 `inSingle` 变量的值设置为 `false`,意味着由单引号包裹的字符串结束了。所以通过以上分析我们得知一件事情,即只要存在于由单引号包裹的字符串内的字符都将被跳过。这么做的目的就是为了避免误把存在于字符串中的管道符当做过滤器的分界线,如下代码所示:
+但是很显然字符 `i` 所对应的 `ASCII` 码不等于 `0x27`,所以这等于什么都没做,直接跳过解析下一个字符。下一个字符是 `d`,它的情况与字符 `i` 一样,也会被跳过。直到遇到最后一个字符 `'`,该字符同样是单引号,所以此时会将 `inSingle` 变量的值设置为 `false`,意味着由单引号包裹的字符串结束了。所以通过以上分析我们得知一件事情,即只要存在于由单引号包裹的字符串内的字符都将被跳过。这么做的目的就是为了避免误把存在于字符串中的管道符当做过滤器的分界线,如下代码所示:
 
 ```html
 <div :key="'id|featId'"></div>
@@ -3079,7 +3079,7 @@ if (c === 0x2f) { // /
 }
 ```
 
-如上代码是一个 `if` 判断语句,它用来判断当前字符所对应的 `ASCII` 码是否等于数字 `0x2f`,其中数字 `0x2f` 就是字符 `/` 所对应的 `ASCII` 码。我们知道正则表达式就是以字符 `/` 开头的,所以当遇到字符 `/` 时,则说明该字符有可能是正则的开始。但至于到底是不是正则的开始还真不一定,前面我们已经提到过了,字符 `/` 还有除法的意义。而判断字符 `/` 到底是正则的开始还是除法却是一件不容的事情。实际上如上代码根本不足以保证所遇到的字符 `/` 就是正则表达式,但还是那句话,这对于 `Vue` 而言已经足够了,我们没必要花大力气在收益很小的地方。
+如上代码是一个 `if` 判断语句,它用来判断当前字符所对应的 `ASCII` 码是否等于数字 `0x2f`,其中数字 `0x2f` 就是字符 `/` 所对应的 `ASCII` 码。我们知道正则表达式就是以字符 `/` 开头的,所以当遇到字符 `/` 时,则说明该字符有可能是正则的开始。但至于到底是不是正则的开始还真不一定,前面我们已经提到过了,字符 `/` 还有除法的意义。而判断字符 `/` 到底是正则的开始还是除法却是一件不容的事情。实际上如上代码根本不足以保证所遇到的字符 `/` 就是正则表达式,但还是那句话,这对于 `Vue` 而言已经足够了,我们没必要花大力气在收益很小的地方。
 
 那我们就来看看如上代码是如何来确定字符 `/` 是正则的开始的,首先我们要明确如果上面这段 `if` 条件语句成立,则说明当前字符为 `/`,此时 `if` 语句块内的代码将被执行,在 `if` 语句块内定义了变量 `j`,它的值为 `i - 1`,也就是说变量 `j` 是 `/` 字符的前一个字符的索引。然后又定义了变量 `p`,接着开启一个 `for` 循环,这个 `for` 循环的作用是找到 `/` 字符之前第一个不为空的字符。如果没找到则说明字符 `/` 之前的所有字符都是空格,或根本就没有字符,如下:
 
@@ -3115,7 +3115,7 @@ if (c === 0x2f) { // /
 
 可以看到如果条件 `!validDivisionCharRE.test(p)` 成立则也会认为当前字符 `/` 是正则的开始。条件 `!validDivisionCharRE.test(p)` 成立说明字符 `/` 之前的字符不能是正则 `validDivisionCharRE` 所匹配的任何一个字符,否则当前字符 `/` 就不被认为是正则的开始。
 
-以上是 `Vue` 的做法,但我们已经说过了,这不足以对字符 `/` 的意义做出准确的判断,但是对 `Vue` 而言足够了。其实我们可以很容易的找出返利,如下:
+以上是 `Vue` 的做法,但我们已经说过了,这不足以对字符 `/` 的意义做出准确的判断,但是对 `Vue` 而言足够了。其实我们可以很容易的找出反例,如下:
 
 ```html
 <div :key="a + /a/.test('abc')"></div>
@@ -3123,7 +3123,7 @@ if (c === 0x2f) { // /
 
 实际上在表达式 `a + /a/.test('abc')` 中出现的斜杠(`/`)的确是定义了正则,但 `Vue` 却不认为它是正则,因为第一个斜杠之前的第一个不为空的字符为加号 `+`。加号存在于正则 `validDivisionCharRE` 中,所以 `Vue` 不认为这里的斜杠是正则的定义。但实际上如上代码简直就是没有任何意义的,假如你非得这么写,那你也完全可以使用计算属性替代。
 
-了解了这些,我们发现 `else` 语句块内的代码就是用来检查环境的,这里的环境指的是字符串环境或正则环境,或圆括号、方括号以及花括号等环境,这些环境信息将会用到其他判断分支的条件语句。
+了解了这些,我们发现 `else` 语句块内的代码就是用来检查环境的,这里的环境指的是字符串环境或正则环境,或圆括号、方括号以及花括号等环境,这些环境信息将会用到其他判断分支的条件语句。
 
 接下来我们来看一下之前没有讲解的一段 `elseif` 条件语句块,如下:
 
@@ -3144,7 +3144,7 @@ else if (
 }
 ```
 
-在本节的前面,我们已经讲解过了该条件语句块的判断条件,如以上条件成立,则说明当前字符为管道符,并且该管道符就是过滤器的分界线。接着来看 `elseif` 语句块内的代码,首先判断了 `expression` 变量是否存在,我们知道 `expression` 变量的初始值为 `undefined`,所以当程序在解析字符串时第一次遇到作为过滤器分界线的管道符时,将会执行如下:
+在本节的前面,我们已经讲解过了该条件语句块的判断条件,如以上条件成立,则说明当前字符为管道符,并且该管道符就是过滤器的分界线。接着来看 `elseif` 语句块内的代码,首先判断了 `expression` 变量是否存在,我们知道 `expression` 变量的初始值为 `undefined`,所以当程序在解析字符串时第一次遇到作为过滤器分界线的管道符时,将会执行如下:
 
 ```js {3-4}
 if (expression === undefined) {
@@ -3158,7 +3158,7 @@ if (expression === undefined) {
 
 如上高亮的两句代码所示,首先将变量 `lastFilterIndex` 的值设置为 `i + 1`,变量 `i` 就是当前遇到的管道符的位置索引,所以 `i + 1` 就应该是管道符下一个字符的位置索引,所以我们可以把 `lastFilterIndex` 变量理解为过滤器的开始。接着对字符串 `exp` 进行截取,其截取的位置恰好是索引为 `i` 的字符,也就是管道符,当然了截取后生成的新字符串是不包含管道符的,同时对截取后生成的新字符串使用 `trim` 方法去除前后空格,最后将处理后的结果赋值给 `expression` 表达式。
 
-为了更直观理解 `lastFilterIndex` 变量和 `expression` 变量,我们举个例子。假设我们有如下代码:
+为了更直观理解 `lastFilterIndex` 变量和 `expression` 变量,我们举个例子。假设我们有如下代码:
 
 ```html
 <div :key="id | featId"></div>
@@ -3195,7 +3195,7 @@ function pushFilter () {
 
 ![](http://7xlolm.com1.z0.glb.clouddn.com/2018-07-08-153103.png)
 
-其中 `lastFilterIndex` 指向的是管道符后面的控制,这里大家需要注意的是变量 `i` 指向的即不是字符 `d` 也不是引号 `"`,而是字符 `d` 后面的字符,这个字符是不存在的。知道了这些,我们就可以知道如下表达式的值:
+其中 `lastFilterIndex` 指向的是管道符后面的空值,这里大家需要注意的是变量 `i` 指向的既不是字符 `d` 也不是引号 `"`,而是字符 `d` 后面的字符,这个字符是不存在的。知道了这些,我们就可以知道如下表达式的值:
 
 ```js
 exp.slice(lastFilterIndex, i).trim()
@@ -3235,7 +3235,7 @@ function pushFilter () {
 }
 ```
 
-在 `pushFilter` 函数内会先将字符串 `'featId'` 添加到数组,接着设置 `lastFilterIndex` 变量的值为 `i + 1`,由于此时变量 `i` 已经是第二个管道符的位置索引,所以 `i + 1` 就应该是第二个管道符后一个字符串你的位置所以,如下是此时的 `lastFilterIndex` 变量的索引指向:
+在 `pushFilter` 函数内会先将字符串 `'featId'` 添加到数组,接着设置 `lastFilterIndex` 变量的值为 `i + 1`,由于此时变量 `i` 已经是第二个管道符的位置索引,所以 `i + 1` 就应该是第二个管道符后一个字符串的位置索引,如下是此时的 `lastFilterIndex` 变量的索引指向:
 
 ![](http://7xlolm.com1.z0.glb.clouddn.com/2018-07-08-155227.png)
 
@@ -3251,7 +3251,7 @@ if (expression === undefined) {
 
 此时代码依然会执行 `elseif` 分支,再次调用 `pushFilter` 函数,我们知道到目前为止我们只将字符串 `'featId'` 添加到了 `filters` 数组中,但我们有两个过滤器,所以还需要将字符串 `'featId2'` 也添加到 `filters` 数组才行,所以这里需要再次执行 `pushFilter` 函数,不过不同的是,此时在 `pushFilter` 函数中,`lastFilterIndex` 变量已经指向了第二个管道符的后一个字符,而变量 `i` 的值也变成了字符串的长度,所以此时被添加到 `filters` 数组的字符串将会是 `'featId2'`。这样两个过滤器的名字就都被添加到 `filters` 数组了。
 
-经过以上代码的处理,对我们来讲最要的两个变量分别是 `expression` 和 `filters`,前者保存着表达式,后者则保存着所有过滤器的名字,假设我们有如下代码:
+经过以上代码的处理,对我们来讲最要的两个变量分别是 `expression` 和 `filters`,前者保存着表达式,后者则保存着所有过滤器的名字,假设我们有如下代码:
 
 ```html
 <div :key="id | a | b | c"></div>
@@ -3334,7 +3334,7 @@ if (filters) {
 <div :key="id"></div>
 ```
 
-如上代码中没有使用过滤器,所以此时 `expression` 变量的值就是字符串 `'id'`。最后 `parseFilters` 函数会将 `expression` 变量为返回值返回:
+如上代码中没有使用过滤器,所以此时 `expression` 变量的值就是字符串 `'id'`。最后 `parseFilters` 函数会将 `expression` 变量为返回值返回:
 
 ```js {3}
 export function parseFilters (exp: string): string {