搜尋
首頁web前端js教程Javascript分號規則的知識介紹(附範例)
Javascript分號規則的知識介紹(附範例)Mar 25, 2019 pm 02:21 PM
javascript文法

這篇文章帶給大家的內容是關於Javascript分號規則的知識介紹(附範例),有一定的參考價值,有需要的朋友可以參考一下,希望對你有幫助。

花點時間搞清楚JS中的分號規則吧~~~不管你喜歡結尾帶分號或省略分號的模式

分號允許的場景

#分號一般允許出現在大部分語句(statement)的結尾,例如do-while statement , var statements, expression statements , continue , return , break statement, throw, debugger 等

栗子:

#栗子:

do Statement while ( Expression ) ;

4+4;

f();

debugger;
只有一個分號; 可以表示空語句-在JS中合法,例如;;; 可解析為三個空語句(empty statement)

空語句可用於輔助產生語法合法的解析結果,如:

while(1);
如果沒有末尾的分號,將會產生解析錯誤- 條件循環後必須跟隨一個語句

分號還會出現在for 迴圈 for ( Expression ; Expression ; Expression ) Statement 中

最後,分號也會出現在字串或正規表示式中- 表示分號本身

分號可以省略的場景

有些場景下分號可以省略,解析器在解析語句時會根據需要自動插入分號,大概流程可以這樣理解:

書寫省略=> 解析器解析時發現缺少時會無法正確解析=> 自動加入分號

so 需要明確能自動插入​​分號的場景,並且明確不會自動插入分號且會造成解析錯誤的情況

規則1:當下一個token (offending token) 和目前解析的token (previous token) 無法組成合法語句,且滿足以下一個或多個條件時,將會在offending token 前插入一個分號:
  • offending token 和previous token 被至少一個換行符分割(LineTerminator),且分號插入的作用不是被解析為空語句(empty statement)
  • offending token 是}
  • previous token 是), 並且插入的分號將被解析為do-while語句的終止分號

還要考慮一種優先級更高的條件:如果插入的分號會被解析為一個空語句,或是for 語句的頭部兩個分號之一,這時不會插入分號(除了do-while 語句的終止分號外)

規則2:當解析到達原始碼檔案(input stream) 的結尾時,將自動新增一個分號標識解析結束

規則3:符合 restricted production 語法的語句- 比較難翻譯,看不懂的可以直接看栗子,這種情況主要描述的是:不應該出現換行符的地方出現換行符導致插入分號引起原語句含義變化

#同時滿足以下條件,將在offending token 前自動插入一個分號:
  • offending token 和previous token 組成合語法的restricted production 語句
  • offending token 出現於restricted production 語句描述中的[no LineTerminaator here] 部分( the token would be the first token for a terminal or nonterminal immediately following the annotation “[no LineTerminator here]” within the restricted production )
  • offending token 和previous token 之間至少存在一個換行符之間至少存在一個換行符(LineTerminator)##;

其中restricted production 包含且只有以下:

UpdateExpression[Yield, Await]:
  LeftHandSideExpression[?Yield, ?Await] [no LineTerminator here] ++
  LeftHandSideExpression[?Yield, ?Await] [no LineTerminator here] --

ContinueStatement[Yield, Await]:
  continue;
  continue [no LineTerminator here] LabelIdentifier[?Yield, ?Await];

BreakStatement[Yield, Await]:
  break;
  break  [no LineTerminator here]  LabelIdentifier[?Yield, ?Await];

ReturnStatement[Yield, Await]:
  return;
  return  [no LineTerminator here]  Expression  [+In, ?Yield, ?Await];

ThrowStatement[Yield, Await]:
  throw [no LineTerminator here] Expression [+In, ?Yield, ?Await];

ArrowFunction[In, Yield, Await]:
  ArrowParameters[?Yield, ?Await] [no LineTerminator here] => ConciseBody[?In]

YieldExpression[In, Await]:
  yield [no LineTerminator here] * AssignmentExpression[?In, +Yield, ?Await]
  yield [no LineTerminator here] AssignmentExpression[?In, +Yield, ?Await]

簡單總結:

使用 a  語句時,變數與   必須在同一行,否則會在   前插入分號導致語意不同

return throw yield continue break 後如果緊跟著換行,將會自動加分號

箭頭函數的=> 之前不應該有換行符

栗子& 可能不符合預期的情況

符合預期情況

// 相当于 42;"hello"
42
"hello"

// offending token 是 }
if(x){y()}

// previous token 是 ) 且插入分号是 do while 语句的结束
var a = 1
do {a++} while(a<p>可能不符合預期的情況</p><pre class="brush:php;toolbar:false">const hey = 'hey'
const you = 'hey'
const heyYou = hey + ' ' + you

['h', 'e', 'y'].forEach((letter) => console.log(letter))

會收到錯誤 Uncaught TypeError: Cannot read property 'forEach' of undefined , 因為you 和['h', 'e', 'y'] 的連接能命中合法語法,故它們之間不會自動插入分號—— 與預期不一致,JS嘗試將代碼解析為:

const hey = 'hey';
const you = 'hey';
const heyYou = hey + ' ' + you['h', 'e', 'y'].forEach((letter) => console.log(letter))

再看一個情況:

const a = 1
const b = 2
const c = a + b
(a + b).toString()

會引發TypeError: b is not a function 報錯,因為會被解釋為:

const a = 1
const b = 2
const c = a + b(a + b).toString()

除了do while 語句外,不會有插入分號作為空語句的其他情況,或作為for 語句頭部的兩個必要分號:

if (a > b)
else c = d

for (a; b
)

以上均不是合法的JS 語句,並且會引起報錯

故以下栗子中的每一個分號都不能省略! !

// for循环没有循环体的情况,每一个分号都不能省略
for (node=getNode();
     node.parent;
     node=node.parent) ;

再看一個有詳細註解的範例:

var         // 这一行不会插入分号 ,因为 下一行的代码不会破坏当前行的代码  
    a = 1   // 这一行会插入分号   
let b = 2   

// 再比如这种情况,你的原意可能是定义 `a` 变量,再执行 `(a + 3).toString()`,
// 但是其实 JavaScript 解析器解析成了,`var a = 2(a + 3).toString()`,
// 这时会抛出错误 Uncaught TypeError: 2 is not a function
var a = 2
(a + 3).toString()

// 同理,下面的代码会被解释为 `a = b(function(){...})()`
a = b
(function(){
...
})()

以上都是未能命中規則1而未插入分號導致解析與預期不符合的情況

看一個基於規則3的例子:

(() => {
  return
  {
    color: 'white'
  }
})()

預期是返回一個包含color 屬性的對象,但事實上return 後會被插入一個分號,而導致最終返回undefined,可以透過在return 後立刻放置花括號{ :

(() => {
  return {
    color: 'white'
  }
})()

省略分號的最佳實踐

不要使用以下单个字符 ( [ / + - 开始一行 , 会极有可能和上一行语句合在一起被解析( ++ 和 -- 不符合单个 +、- 字符)

注意 return break throw continue 语句,如果需要跟随参数或表达式,把它添加到和这些语句同一行,针对 return 返回内容较多的情况 (大对象,柯里化调用,多行字符串等),可以参考规则1,避免命中该规则而引起非预期的分号插入,比如:

return obj.method('abc')
          .method('xyz')
          .method('pqr')
 
return "a long string\n"
     + "continued across\n"
     + "several lines"
 
totalArea = rect_a.height * rect_a.width
          + rect_b.height * rect_b.width
          + circ.radius * circ.radius * Math.PI
后缀运算符 ++ -- 需要和操作变量在同一行使用

当然大部分工程化情况下,我们最终会配合Eslint使用带分号或省略分号规范~~~

本篇文章到这里就已经全部结束了,更多其他精彩内容可以关注PHP中文网的JavaScript视频教程栏目!

以上是Javascript分號規則的知識介紹(附範例)的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述
本文轉載於:segmentfault。如有侵權,請聯絡admin@php.cn刪除
es6数组怎么去掉重复并且重新排序es6数组怎么去掉重复并且重新排序May 05, 2022 pm 07:08 PM

去掉重复并排序的方法:1、使用“Array.from(new Set(arr))”或者“[…new Set(arr)]”语句,去掉数组中的重复元素,返回去重后的新数组;2、利用sort()对去重数组进行排序,语法“去重数组.sort()”。

JavaScript的Symbol类型、隐藏属性及全局注册表详解JavaScript的Symbol类型、隐藏属性及全局注册表详解Jun 02, 2022 am 11:50 AM

本篇文章给大家带来了关于JavaScript的相关知识,其中主要介绍了关于Symbol类型、隐藏属性及全局注册表的相关问题,包括了Symbol类型的描述、Symbol不会隐式转字符串等问题,下面一起来看一下,希望对大家有帮助。

原来利用纯CSS也能实现文字轮播与图片轮播!原来利用纯CSS也能实现文字轮播与图片轮播!Jun 10, 2022 pm 01:00 PM

怎么制作文字轮播与图片轮播?大家第一想到的是不是利用js,其实利用纯CSS也能实现文字轮播与图片轮播,下面来看看实现方法,希望对大家有所帮助!

JavaScript对象的构造函数和new操作符(实例详解)JavaScript对象的构造函数和new操作符(实例详解)May 10, 2022 pm 06:16 PM

本篇文章给大家带来了关于JavaScript的相关知识,其中主要介绍了关于对象的构造函数和new操作符,构造函数是所有对象的成员方法中,最早被调用的那个,下面一起来看一下吧,希望对大家有帮助。

JavaScript面向对象详细解析之属性描述符JavaScript面向对象详细解析之属性描述符May 27, 2022 pm 05:29 PM

本篇文章给大家带来了关于JavaScript的相关知识,其中主要介绍了关于面向对象的相关问题,包括了属性描述符、数据描述符、存取描述符等等内容,下面一起来看一下,希望对大家有帮助。

javascript怎么移除元素点击事件javascript怎么移除元素点击事件Apr 11, 2022 pm 04:51 PM

方法:1、利用“点击元素对象.unbind("click");”方法,该方法可以移除被选元素的事件处理程序;2、利用“点击元素对象.off("click");”方法,该方法可以移除通过on()方法添加的事件处理程序。

foreach是es6里的吗foreach是es6里的吗May 05, 2022 pm 05:59 PM

foreach不是es6的方法。foreach是es3中一个遍历数组的方法,可以调用数组的每个元素,并将元素传给回调函数进行处理,语法“array.forEach(function(当前元素,索引,数组){...})”;该方法不处理空数组。

整理总结JavaScript常见的BOM操作整理总结JavaScript常见的BOM操作Jun 01, 2022 am 11:43 AM

本篇文章给大家带来了关于JavaScript的相关知识,其中主要介绍了关于BOM操作的相关问题,包括了window对象的常见事件、JavaScript执行机制等等相关内容,下面一起来看一下,希望对大家有帮助。

See all articles

熱AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover

AI Clothes Remover

用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool

Undress AI Tool

免費脫衣圖片

Clothoff.io

Clothoff.io

AI脫衣器

AI Hentai Generator

AI Hentai Generator

免費產生 AI 無盡。

熱門文章

R.E.P.O.能量晶體解釋及其做什麼(黃色晶體)
3 週前By尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.最佳圖形設置
3 週前By尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.如果您聽不到任何人,如何修復音頻
3 週前By尊渡假赌尊渡假赌尊渡假赌
WWE 2K25:如何解鎖Myrise中的所有內容
3 週前By尊渡假赌尊渡假赌尊渡假赌

熱工具

mPDF

mPDF

mPDF是一個PHP庫,可以從UTF-8編碼的HTML產生PDF檔案。原作者Ian Back編寫mPDF以從他的網站上「即時」輸出PDF文件,並處理不同的語言。與原始腳本如HTML2FPDF相比,它的速度較慢,並且在使用Unicode字體時產生的檔案較大,但支援CSS樣式等,並進行了大量增強。支援幾乎所有語言,包括RTL(阿拉伯語和希伯來語)和CJK(中日韓)。支援嵌套的區塊級元素(如P、DIV),

MinGW - Minimalist GNU for Windows

MinGW - Minimalist GNU for Windows

這個專案正在遷移到osdn.net/projects/mingw的過程中,你可以繼續在那裡關注我們。 MinGW:GNU編譯器集合(GCC)的本機Windows移植版本,可自由分發的導入函式庫和用於建置本機Windows應用程式的頭檔;包括對MSVC執行時間的擴展,以支援C99功能。 MinGW的所有軟體都可以在64位元Windows平台上運作。

SublimeText3 英文版

SublimeText3 英文版

推薦:為Win版本,支援程式碼提示!

DVWA

DVWA

Damn Vulnerable Web App (DVWA) 是一個PHP/MySQL的Web應用程序,非常容易受到攻擊。它的主要目標是成為安全專業人員在合法環境中測試自己的技能和工具的輔助工具,幫助Web開發人員更好地理解保護網路應用程式的過程,並幫助教師/學生在課堂環境中教授/學習Web應用程式安全性。 DVWA的目標是透過簡單直接的介面練習一些最常見的Web漏洞,難度各不相同。請注意,該軟體中

VSCode Windows 64位元 下載

VSCode Windows 64位元 下載

微軟推出的免費、功能強大的一款IDE編輯器