說明
每天10分鐘,重構你的前端知識體系專欄筆記。
一、JavaScript 的詞法(lexical grammar)
會被從左到右掃描,并被轉換為一系列的輸入元素,包括
ECMAScript 源碼文本
。ECMAScript 定義了一些關鍵字、字面量以及行尾分号補全的規則。
token、控制符、行終止符、注釋和空白符
可以參考MDN文檔–詞法文法
1.1、分類
-
空白字元WhiteSpace
-
換行符LineTerminator
-
注釋Comment
-
詞Token
-
:典型案例就是使用的變量名,注意這裡關鍵字也包含在内。IdentifierName 辨別符名稱
-
:使用的運算符和大括号等符号。Punctuator 符号
-
:就是寫的數字。NumericLiteral 數字直接量
-
:就是用單引号或者雙引号引起來的直接量。StringLiteral 字元串直接量
-
:用反引号 ` 括起來的直接量。Template 字元串模闆
1.2、特别之處
1、除法和正規表達式沖突問題
JavaScript 不但支援除法運算符和
/
,還支援用斜杠括起來的正規表達式
/=
。
/.../
解決方案:是定義兩組詞法,然後靠文法分析傳一個标志給詞法分析器,讓它來決定使用哪一套詞法。
2、字元串模闆
理論上,内部可以放任何
${ }
,而這些代碼是以
JavaScript 表達式代碼
結尾的,也就是說,這部分詞法不允許出現
}
運算符。
}
// <!-- 模闆文法 -->
`Hello, ${world}`
3、四種詞法定義
- InputElementDiv
- InputElementRegExp
- InputElementRegExpOrTemplateTail
- InputElementTemplateTail
二、空白符号 Whitespace
2.1、空白符号分類
-
(或稱<HT>
) 是<TAB>
,是縮進U+0009
符,字元串中寫的TAB
。\t
-
是<VT>
,也就是垂直方向的U+000B
。TAB 符 \v
-
是<FF>
,U+000C
,分頁符,字元串直接量中寫作Form Feed
。\f
-
是<SP>
,就是最普通的空格。U+0020
-
是<NBSP>
,非斷行空格,它是U+00A0
的一個變體,在文字排版中,可以避免因為空格在此處發生斷行,其它方面和普通空格完全一樣。SP
-
(舊稱<ZWNBSP>
) 是<BOM>
,這是U+FEFF
新加入的空白符,是ES5
中的零寬非斷行空格,在以Unicode
編碼的檔案中,常常在檔案首插入一個額外的UTF 格式
,解析U+FEFF
的程式可以根據UTF 檔案
的表示方法猜測檔案采用哪種U+FEFF
方式。這個字元也叫做UTF 編碼
。bit order mark
2.2、所有的 Unicode 中的空格分類
三、換行符 LineTerminator
3.1、四種換行符
-
:是<LF>
,就是最正常換行符,在字元串中的U+000A
\n
-
:是<CR>
,這個字元真正意義上的U+000D
,在字元串中是回車
\r
-
:是<LS>
,是U+2028
中的行分隔符。Unicode
-
:是<PS>
,是U+2029
中的段落分隔符。Unicode
注意:換行符會影響 JavaScript 的兩個重要文法特性:
自動插入分号
和
no line terminator
規則。
四、注釋 Comment
// 多行注釋
/* MultiLineCommentChars */
// 單行注釋
// SingleLineCommentChars
五、辨別符名稱 IdentifierName
可以以
IdentifierName
,
美元符$
或者
下劃線_
開始,除了開始字元以外,還可以使用
Unicode 字母
中的連接配接标記、數字、以及連接配接符号。
Unicode
關鍵字
await break case catch class const
continue debugger default delete do else
export extends finally for function if
import ininstance of new return super
switch this throw try typeof
var void while with yield
// 為了未來使用而保留的關鍵字
enum
// 在嚴格模式下還有
implements package protected
interface private public
NullLiteral(null)和 BooleanLiteral(true false)
也是保留字。
僅當不是保留字的時候,
IdentifierName
會被解析為
Identifier
。
六、符号 Punctuator
{ ( ) [ ] . ... ; , < > <= >= == != === !==
+ - * % ** ++ -- << >> >>> & | ^ ! ~ && ||
? : = += -= *= %= **= <<= >>= >>>= &= |=
^= => / /= }
七、數字直接量 NumericLiteral
JavaScript 規範中規定的數字直接量可以支援四種寫法:十進制數、二進制整數、八進制整數和十六進制整數。
1、十進制的 Number 可以帶小數,小數點前後部分都可以省略,但是不能同時省略
.01 // 0.01
12. // 12
12.01 // 12.01
2、12.toString() 為什麼會報錯?
12.toString()
// Uncaught SyntaxError: Invalid or unexpected token
// 原因: `12.` 會被當做省略了小數點後面部分的數字而看成一個整體,相當于執行了12toString(),是以會報錯
// 解決:加入空格讓其單獨成為一個 token
12 .toString() // "12"
// 或者加一個.
12..toString() // "12"
另外科學計數法跟進制就不寫了。。。。
八、字元串直接量 StringLiteral
// 雙引号
" DoubleStringCharacters "
// 單引号
' SingleStringCharacters '
8.1、單字元轉義
即一個反斜杠 \
後面跟一個字元這種形式。
九、正規表達式直接量 RegularExpressionLiteral
正規表達式由 Body 和 Flags 兩部分組成
/RegularExpressionBody/g
其中 Body 部分至少有一個字元,第一個字元不能是 (因為 / 跟多行注釋有詞法沖突)。
十、字元串模闆 Template
`a${b}c${d}e`
/*
// 被拆成了五個部分
`a${ // 這個被稱為模闆頭
b // 普通辨別符
}c${ // 被稱為模闆中段
d // 普通辨別符
}e` // 被稱為模闆尾
*/
function kaimo(){
console.log(arguments);
}
var temp = "kaimo"
kaimo`hello ${temp} !`
// [["hello ", " !"], "kaimo"]