91超碰碰碰碰久久久久久综合_超碰av人澡人澡人澡人澡人掠_国产黄大片在线观看画质优化_txt小说免费全本

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

JavaScript詞法都有哪些

發布時間:2021-09-30 14:55:49 來源:億速云 閱讀:144 作者:柒染 欄目:web開發

這篇文章將為大家詳細講解有關JavaScript詞法都有哪些,文章內容質量較高,因此小編分享給大家做個參考,希望大家閱讀完這篇文章后對相關知識有一定的了解。

InputElement 輸入元素

輸入元素是JS詞法掃描程序拿到的最基本元素了,也就是JS程序源代碼中表達特定意義的"單詞"。

輸入元素共分為四種:

InputElement ::
    WhiteSpace
    Comment
    Token
    LineTerminator

值得注意的是,JS規范里面其實定義了兩種InputElement ,如下所示

InputElementDiv ::
    WhiteSpace
    Comment
    Token
    LineTerminator
    DivPunctuator
InputElementRegExp ::
    WhiteSpace
    Comment
    Token
    LineTerminator
    RegularExpressionLiteral

這么做是因為JS的除法運算符和正則表達式直接量都使用了/字符,在詞法分析階段,是無法區分二者的。所以JavaScript的詞法分析有兩種狀態,一種狀態是掃描InputElementDiv,另一種狀態是掃描InputElementRegExp,又所以,JS的詞法分析器應該有兩種狀態,由語法分析器來設置,JavaScript的詞法分析和語法分析必須交錯進行。

在學習web前端的過程中,難免會遇到很多的問題,這些問題可能會困擾你許久,為此我有個web開發學習交流群( 545667817 ),
里面都是  ITPUB  的小伙伴,并整理了一份最全面前端學習資料,從最基礎的HTML+CSS+JS 到移動端HTML5的項目實戰的學習資料都有整理,想學習的都可以申請加入,大家互相學習,互相交流,共同進步,每日分享不同的學習資料!

下面的一個例子說明了除法和正則表達式寫法的沖突問題:

if(a+b)/a/g;
(a+b)/a/g;

可以看到完全相同的/a/g(而且前面一段字符也相同),可能被理解為除法或者正則表達式。因為必須區分所處的語法環境,所以單單靠詞法分析無論如何也無法決定該用除法還是正則表達式來理解。

因為基本上沒有任何編輯環境會對文本做語法分析,這個問題也造成了很多語法著色系統無法很好地處理JS正則表達式。

以非語言實現者的角度,完全應該按照最上面一段產生式去理解JS的詞法。

WhiteSpace空白符

這個詞相信不用細說,所有JS程序員都比較熟悉。JavaScript接受5種ASCII字符為空白符,BOM以及Unicode分類中所有屬于whitespace分類的字符也可以作為空白符使用:

WhiteSpace ::
    <TAB>
    <VT>
    <FF>
    <SP>
    <NBSP>
    <BOM>
    <USP>

其中,<TAB>是U+0009,是縮進TAB符,也就是字符串中寫的'\t'。

<VT>是U+000B,也就是垂直方向的TAB符'\v',這個字符在鍵盤上很難打出來,所以很少用到。

<FF>是U+000C,Form Feed,分頁符,字符串直接量中寫作'\f',現代已經很少有打印源程序的事情發生了,所以這個字符在JS源代碼中很少用到。

<SP>是U+0020,就是最普通的空格了。

<NBSP>是U+00A0,非斷行空格,它是SP的一個變體,在文字排版中,可以避免因為空格在此處發生斷行,其它方面和普通空格完全一樣。多數的JS編輯環境都會把它當做普通空格(因為一般源代碼編輯環境根本就不會自動折行……)

<BOM>是U+FEFF,這是ES5新加入的空白符,是Unicode中的零寬非斷行空格,在以UTF格式編碼的文件中,常常在文件首插入一個額外的U+FEFF,解析UTF文件的程序可以根據U+FEFF的表示方法猜測文件采用哪種UTF編碼方式。這個字符也叫做"bit order mark"。

<USP>表示Unicode中所有的"separator, space(Zs)"分類中的字符,包括:

字符名稱你瀏覽器中的顯示
U+0020SPACE
U+00A0NO-BREAK SPACE
U+1680OGHAM SPACE MARK
U+180EMONGOLIAN VOWEL SEPARATOR
?
U+2000EN QUAD
U+2001EM QUAD
U+2002EN SPACE
U+2003EM SPACE
U+2004THREE-PER-EM SPACE
U+2005FOUR-PER-EM SPACE
U+2006SIX-PER-EM SPACE
U+2007FIGURE SPACE
U+2008PUNCTUATION SPACE
U+2009THIN SPACE
U+200AHAIR SPACE
U+202FNARROW NO-BREAK SPACE
U+205FMEDIUM MATHEMATICAL SPACE
U+3000IDEOGRAPHIC SPACE

注意雖然JS規范承認這些字符可以被用做空白字符,但是除非對源代碼的打印、排版有特別的需求,還是應該盡量使用<SP>,尤其是考慮到,相當一批字體無法支持<USP>中的全部字符。

根據一些團隊的編碼規范,<TAB>常常用于縮進。編程語言中關于用<TAB>還是四個<SP>做縮進的爭論從未停止過,此處就不加討論了。

JS中,WhiteSpace的大部分用途是分隔token和保持代碼整齊美觀,基本上詞法分析器產生的WhiteSpace都會被語法分析器直接丟棄。

所以一些WhiteSpace能夠被去掉而完全不影響程序的執行效果。但是也有一些WhiteSpace必須存在的情況,考慮下面代碼:

1 .toString();
1.toString(); //報錯

上面一段代碼中,空白符分隔了1和.,因此它們被理解為兩個token。

1.["toString"]();
1 .["toString"](); //報錯

相反的情況。

LineTerminator行終結符

這個也是一個非常常見的概念了,JS中只提供了4種字符作為換行符:

LineTerminator ::
    <LF>
    <CR>
    <LS>
    <PS>

其中,<LF>是U+000A,就是最正常換行符,在字符串中的'\n'。

<CR>是U+000D,這個字符真正意義上的"回車",在字符串中是'\r',在一部分Windows風格文本編輯器中,換行是兩個字符\r\n。

<LS>是U+2028,是Unicode中的行分隔符。

<PS>是U+2029,是Unicode中的段落分隔符。

大部分LineTerminator在被詞法分析器掃描出之后,會被語法分析器丟棄,但是換行符會影響JS的兩個重要語法特性:自動插入分號和"no line terminator"規則。

考慮下面三段代碼:

var a = 1 , b = 1;
a
++
b

按照JS語法的自動插入分號規則,代碼解釋可能產生歧義。

但是因為后自增運算符有no line terminator的限制,所以實際結果等價于:

var a = 1 , b = 1;
a;
++b;

考慮以下兩段代碼:

return
    123;
return 123;

因為return有no line terminator的限制,所以第一段代碼實際等同于

return;
123;

Comment注釋

JS的注釋分為單行注釋和多行注釋兩種: 

Comment :: 
    MultiLineComment 
    SingleLineComment

多行注釋定義如下:

MultiLineComment :: 
    /* MultiLineCommentCharsopt */ 
MultiLineCommentChars :: 
    MultiLineNotAsteriskChar MultiLineCommentCharsopt 
    * PostAsteriskCommentCharsopt PostAsteriskCommentChars :: 
    MultiLineNotForwardSlashOrAsteriskChar MultiLineCommentCharsopt 
    * PostAsteriskCommentCharsopt MultiLineNotAsteriskChar :: 
    SourceCharacter but not asterisk * 
MultiLineNotForwardSlashOrAsteriskChar :: 
    SourceCharacter but not forward-slash / orasterisk *

這個定義略微有些復雜,實際上這就是我們所熟知的JS多行注釋語法的嚴格描述。

多行注釋中允許自由地出現MultiLineNotAsteriskChar ,也就是除了*之外的所有字符。而每一個*之后,不能出現正斜杠符/

單行注釋則比較簡單:

SingleLineComment ::
    // SingleLineCommentCharsoptSingleLineCommentChars ::
    SingleLineCommentChar SingleLineCommentCharsoptSingleLineCommentChar ::
    SourceCharacter but not LineTerminator

除了四種LineTerminator之外,所有字符都可以作為單行注釋。

一般情況下,不論是單行還是多行注釋都不會影響程序的意義,但是含有LineTerminator的多行注釋會影響到自動插入分號規則:

return/*
    */123;
return /**/ 123;

兩者會產生不同的效果。

Token

Token是JS中所有能被引擎理解的最小語義單元。

JS中有4種Token:

Token ::
    IdentifierName 
    Punctuator 
    NumericLiteral 
    StringLiteral

如果不考慮除法和正則的沖突問題,Token還應該包括RegularExpressionLiteral,而Punctuator中也應該添加 / 和 /=兩種符號。

IdentifierName

IdentifierName的定義為:

IdentifierName ::
    IdentifierStart
    IdentifierName IdentifierPart
IdentifierStart ::
    UnicodeLetter
    $
    _ 
    \ UnicodeEscapeSequence
IdentifierPart ::
    IdentifierStart
    UnicodeCombiningMark
    UnicodeDigit
    UnicodeConnectorPunctuation
    <ZWNJ>
    <ZWJ>

IdentifierName可以以美元符$下劃線_ 或者Unicode字母開始,除了開始字符以外,IdentifierName中還可以使用Unicode中的連接標記、數字、以及連接符號。

IdentifierName的任意字符可以使用JS的Unicode轉義寫法,使用Unicode轉義寫法時,沒有任何字符限制。

IdentifierName可以是Identifier、NullLiteral、BooleanLiteral或者keyword,在ObjectLiteral中,IdentifierName還可以被直接當做屬性名稱使用。

僅當不是保留字的時候,IdentifierName會被解析為Identifier。

 UnicodeLetter, UnicodeCombiningMark, UnicodeDigit, UnicodeConnectorPunctuation各自對應幾個Unicode的分類。

JS詞法名Unicode分類名code字符數
UnicodeLetterUppercase letterLu1441
Lowercase letterLl1751
Titlecase letterLt31
Modifier letterLm237
Other letterLo11788
Letter numberNl224
UnicodeCombiningMarkNon-spacing markMn1280
Combining spacing markMc353
UnicodeDigitDecimal numberNd460
UnicodeConnectorPunctuationConnector punctuationPc10

注意<ZWNJ>和<ZWJ>是ES5新加入的兩個格式控制字符,但是目前為止實測還沒有瀏覽器支持。

JS中的關鍵字有:

Keyword :: one of
    break do instanceof typeof case else new var catch finally return void continue for switch while debugger function this with default if throw delete in try

還有7個為了未來使用而保留的關鍵字: 

FutureReservedKeyword :: one of
    class enum extends super const export import

在嚴格模式下,有一些額外的為未來使用而保留的關鍵字:

implements let private public interface package protected static yield

除了這些之外,NullLiteral: 

NullLiteral ::
    null

和BooleanLiteral:

BooleanLiteral ::
    true false

也是保留字,不能用于Identifier。

Punctuator

JavaScript使用48個運算符,因為前面提到的除法和正則問題, /和/=兩個運算符被拆分為DivPunctuator。其余的運算符為:

 Punctuator :: one of
    { } ( ) [ ] . ; , < > <= >= == != === !== + - * % ++ -- << >> >>> & | ^ ! ~ && || ? : = += -= *= %= <<= >>= >>>= &= |= ^=

所有運算符在語法分析器中作為不同的symbol出現。

NumericLiteral

JS規范中規定的數字直接量可以支持兩種寫法:十進制和十六進制整數,盡管標準中沒有提到,但是大部分JS實現還支持以0開頭的八進制整數寫法。

所以實際上JS的NumericLiteral產生式應該是這樣的:

NumericLiteral :: 
    DecimalLiteral
    HexIntegerLiteral
    OctalIntegerLiteralnot-standard

只有十進制可以表示浮點數,DecimalLiteral 定義如下:

DecimalLiteral ::
    DecimalIntegerLiteral . DecimalDigitsopt ExponentPartopt
    . DecimalDigits ExponentPartopt
    DecimalIntegerLiteral ExponentPartoptDecimalIntegerLiteral ::
    0 
    NonZeroDigit DecimalDigitsoptDecimalDigits ::
    DecimalDigit
    DecimalDigits DecimalDigit
DecimalDigit :: one of
    0 1 2 3 4 5 6 7 8 9
NonZeroDigit:: one of
    1 2 3 4 5 6 7 8 9
ExponentPart::
    ExponentIndicator SignedInteger
ExponentIndicator :: one of
    e E
SignedInteger ::
    DecimalDigits
    + DecimalDigits
    - DecimalDigits

JS中的StringLiteral支持單引號和雙引號兩種寫法。

十進制數的小數點前和小數點后均可以省略, 所以 1. 和 .1 都是合法的數字直接量,特別地,除了0之外,十進制數不能以0開頭(這其實是為了八進制整數預留的)。

.同時還是一個Punctuator,在詞法分析階段,.123 應該優先被嘗試理解為 NumericLiteral ,而非 Punctuator NumericLiteral。

十六進制整數產生式如下:

HexIntegerLiteral ::
    0x HexDigit
    0X HexDigit
    HexIntegerLiteral HexDigit
HexDigit :: one of
    0 1 2 3 4 5 6 7 8 9 a b c d e f A B C D E F

JS中支持0x標記的大小寫形式,十六進制數字中的大小寫也可以任意使用。

八進制整數是非標準的,但是大多數引擎都支持:

OctalIntegerLiteral :: 
    0 OctalDigit
    OctalIntegerLiteral OctalDigit 
OctalDigit :: one of
    0 1 2 3 4 5 6 7

StringLiteral

JS中的StringLiteral支持單引號和雙引號兩種寫法。

StringLiteral ::
    " DoubleStringCharactersopt "
    ' SingleStringCharactersopt '

單雙引號的區別僅僅在于寫法,在雙引號字符串直接量中,雙引號必須轉義,在單引號字符串直接量中,單引號必須轉義

DoubleStringCharacters ::
    DoubleStringCharacter DoubleStringCharactersoptSingleStringCharacters ::
    SingleStringCharacter SingleStringCharactersoptDoubleStringCharacter ::
    SourceCharacter but not double-quote " or backslash \ or LineTerminator
    \ EscapeSequence
    LineContinuation
SingleStringCharacter ::
    SourceCharacter but not single-quote ' orbackslash \ or LineTerminator
    \ EscapeSequence
    LineContinuation

字符串中其他必須轉義的字符是\和所有換行符。

JS中支持四種轉義形式,還有一種雖然標準沒有定義,但是大部分實現都支持的八進制轉義

EscapeSequence ::
    CharacterEscapeSequence
    0 [lookahead no DecimalDigit]
    HexEscapeSequence
    UnicodeEscapeSequence
    OctalEscapeSequencenot-standard

第一種是單字符轉義。 即一個反斜杠\ 后面跟一個字符這種形式。

CharacterEscapeSequence ::
    SingleEscapeCharacter
    NonEscapeCharacter
SingleEscapeCharacter :: one of
    ' " \ b f n r t v
NonEscapeCharacter ::
    SourceCharacter but notEscapeCharacter or LineTerminator

有特別意義的字符包括有SingleEscapeCharacter所定義的9種,見下表:

轉義字符轉義結果你瀏覽器中的顯示
'U+0022
"
"U+0027
'
\U+005C
\
bU+0008

fU+000C
nU+000A
rU+000D
tU+0009
vU+000B

除了這9種字符、數字、x和u以及所有的換行符之外,其它字符經過\轉義都是自身。

十六進制轉義只支持兩位,也就是說,這種寫法只支持ASCII字符:

HexEscapeSequence ::
    x HexDigit HexDigit

Unicode轉義可以支持BMP中的所有字符:

UnicodeEscapeSequence ::
    u HexDigit HexDigit HexDigit HexDigit

LineContinuation可以被理解為一種特別的轉義。寫字符串直接量時靈活使用LineContinuation可以增加可讀性。

LineContinuation ::
    \ LineTerminatorSequence
LineTerminatorSequence ::
    <LF>
    <CR> [lookahead no <LF> ]
    <LS>
    <PS>
    <CR>
    <CR> <LF>

為了適應Windows風格的文本,JS把"\r\n"作為一個換行符使用。

注意因為CR在某些windows風格的編輯器中沒法顯示出來,所以亂用的話會產生奇怪的效果。

RegularExpressionLiteral

正則表達式由Body和Flags兩部分組成:

RegularExpressionLiteral ::
    / RegularExpressionBody / RegularExpressionFlags

其中Body部分至少有一個字符,第一個字符不能是*(因為/*跟多行注釋有詞法沖突。)

RegularExpressionBody ::
    RegularExpressionFirstChar RegularExpressionChars
RegularExpressionChars ::
    [empty]
    RegularExpressionChars RegularExpressionChar
RegularExpressionFirstChar ::
    RegularExpressionNonTerminator but not * or \ or / or [ 
    RegularExpressionBackslashSequence
    RegularExpressionClass
RegularExpressionChar ::
    RegularExpressionNonTerminator but not \ or / or [ 
    RegularExpressionBackslashSequence
    RegularExpressionClass

除了\  / 和 [ 三個字符之外,JS正則表達式中的字符都是普通字符。

RegularExpressionBackslashSequence ::
    \ RegularExpressionNonTerminator
RegularExpressionNonTerminator ::
    SourceCharacter but not LineTerminator

用 \和一個非換行符可以組成一個RegularExpressionBackslashSequence,這種方式可以用于表示正則表達式中的有特殊意義的字符。

RegularExpressionClass ::
    [ RegularExpressionClassChars ]

正則表達式中,用一對方括號表示class。class中的特殊字符僅僅為]和\。

class允許為空。

class中也支持轉義。

RegularExpressionClassChars ::
    [empty]
    RegularExpressionClassChars RegularExpressionClassChar
RegularExpressionClassChar ::
    RegularExpressionNonTerminator but not ] or \ 
    RegularExpressionBackslashSequence

正則表達式中的flag在詞法階段不會限制字符,雖然只有ig幾個是有效的,但是任何IdentifierPart序列在詞法階段都會被認為是合法的。

RegularExpressionFlags ::
    [empty]
    RegularExpressionFlags IdentifierPart

一些詞法分析認為合法,但是實際上不符合正則語法的例子:

附表 JS詞法摘要

英文名名稱簡述示例
InputElement輸入元素一切JS中合法的"詞"
┣Comments注釋用于幫助閱讀的文本
┃┣SingleLineComments單行注釋以//起始的單行注釋
//I'm comments
┃┗MultiLineComments多行注釋以/*起始以*/結束的注釋
/*I'm comments,too.*/
┣WhiteSpace空白起到分隔或者保持美觀作用的空白字符
┣Token詞法標記一切JS中有實際意義的詞法標記
┃┣IdentifierName標識名稱以字母或_或$開始的一個單詞,可以用于屬性名
┃┃┣Identifier標識符非保留字的IdentifierName,可以用于變量名或者屬性名
abc
┃┃┣Keyword關鍵字有特殊語法意義的IdentifierName
while
┃┃┣NullLiteralNull直接量表示一個Null類型的值
null
┃┃┗BooleanLiteral布爾直接量表示一個Boolean類型的值
true
┃┣Punctuator標點符號表示特殊意義的標點符號
*
┃┣NumericLiteral數字直接量表示一個Number類型的值
.12e-10
┃┣StringLiteral字符串直接量表示一個String類型的值
"Hello world!"
┃┗RegularExpressionLiteral正則表達式直接量表示一個RegularExpression類的對象
/[a-z]+$$/g
┗LineTerminator行終結符起到分隔或者保持美觀作用的換行字符,可能會影響自動插入分號

附表 所有JS詞法中的不可見字符

簡寫字符概述
<TAB>U+0009tab符,用于空白
<VT>U+000B豎向tab符,用于空白
<FF>U+000C換頁,用于空白
<SP>U+0020空格,用于空白
<NBSP>U+00A0非斷行空格,用于空白
<BOM>U+FEFF零寬非斷行空格,字節序標記,用于空白
<ZWNJ>U+200C零寬非連接符,用于標識符
<ZWJ>U+200D零寬連接符,用于標識符
<LF>U+000A換行,用于行終結符
<CR>U+000D回車,用于行終結符
<LS>U+2028行分隔符,用于行終結符
<PS>U+2029頁分隔符,用于行終結符

關于JavaScript詞法都有哪些就分享到這里了,希望以上內容可以對大家有一定的幫助,可以學到更多知識。如果覺得文章不錯,可以把它分享出去讓更多的人看到。

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

即墨市| 新沂市| 铁岭县| 太仆寺旗| 德安县| 泾川县| 手机| 临泽县| 建水县| 麻江县| 文登市| 临颍县| 博野县| 临汾市| 巩留县| 桐柏县| 佛学| 北流市| 法库县| 崇信县| 兴山县| 读书| 浦江县| 嘉鱼县| 太白县| 曲周县| 泽州县| 开封市| 东乡县| 五莲县| 衡东县| 阳朔县| 防城港市| 栖霞市| 永安市| 庆元县| 满城县| 盐边县| 淄博市| 嘉义市| 筠连县|