語法


標籤: 語法,語句,表達式,you don't know javascriptjavascript


語句和表達式

  • 「語句」和「表達式」在JavaScript中不一樣的兩個概念。
var a = 3 * 6;
var b = a;
b;
複製代碼

表達式:前端

  1. 第一行 3 * 6
  2. 第二行 a
  3. 第三行 b

語句: 這三行代碼叫作包含表達式的語句。java

  • 第三行中只有一個表達式b,一般叫作「表達式語句」

語句的結果值

  • 語句都有一個結果值(statement completion value, undefined也算)。
  • 能夠在瀏覽器控制檯中輸入語句,老是返回的是最後一條語句的結果值。
> var a = 30
< undefined
 > a = 40
< 40
複製代碼
  • 聲明語句的返回值是undefined。
  • 賦值語句返回的是被賦值變量賦值後的值。

{..}代碼塊的結果值

  • 代碼塊的結果值是最後一條語句的結果。
> {
    var b = 10;
    b = 20
  }
< 20
複製代碼
  • 語句的結果值不能經過變量賦值的方式取到
var result = {
  var b = 10;
  b = 20
}
// SyntaxError
複製代碼
  • 能夠用eval(..)得到語句的結果值,可是JavaScript編程歷來都不推薦使用eval()。
var result = eval(`{ var b = 10; b = 20 }`)

result // 20
複製代碼

表達式的反作用

  • 中文翻譯版將effect譯爲反作用,有點難以理解。
  • 我的理解爲,表達式有返回值是表達式的一個重要特性,可是大部分表達式還會有運算做用,他會對程序中的其餘部分(變量)產生影響。簡單理解爲有運算符的表達式就會有effect
var a = 30;

a++; // 30
a; // 31

++a; // 32
a; // 32
複製代碼
  • 反作用產生的時間不一樣,++a在反作用(a自增)產生以後返回值,而a++在反作用產生以前返回值。es6

  • delete表達式也有返回值,刪除不存在或可配置的屬性,返回true,不然返回false或者報錯。web

賦值運算符

  • 研究賦值運算符的反作用和返回值在連等語句中有重要意義。
var a,b,c

a = b = c = 30;
// c = 30的反作用是將30複製給c,返回值是表達式c = 30的結果值,一樣原理左依次執行。
複製代碼
  • 利用表達式的返回值和反作用將語句合併。
function foo (a) {
  return a > 20
}

var num = 30

if (num > 10) {
  var result = foo(num)
  if (result) {
    console.log(result)
  }
}

複製代碼

上面的兩個if能夠合併成chrome

var result
if (num > 10 && (result = foo(num))) {
  console.log(result)
}
複製代碼

大括號

  • JavaScript中一樣的語法在不一樣狀況下會有不一樣的解釋,其中大括號就是典型。

對象字面量

  • 字面量形式定義變量
var a = {
    foo: 1
  }
複製代碼

代碼塊

  • 如下代碼使用的{}定義代碼塊併產生了es6中的塊級做用域
{
  let a = 10;
  a
}
複製代碼

對象解構

  • 這部分以前學習過,再也不重複。
let {a, b} = {a: 10, b: 20}
複製代碼

else if問題

  • ifelse後面的語句只有一句時能夠省略{}
if (a) console.log(a)
複製代碼
  • else if不是JavaScript的語法規則,是開發者發明的,很好用,因此極爲常見。編程

  • else if表示else後跟了一個省略{}if代碼塊。json

  • 因不推薦將ifelse後面的{}省略,因此else if在這個層面上講是不規範的寫法。小程序

if (a) {

} else if (b) {

}

// 規範寫法
if (a) {

} else {
  if (b) {

  }
}
複製代碼

大括號的「歧義」

  • 這個「歧義」是指開發者難以判斷大括號表明的是什麼(對象?代碼塊?),而不是指引擎解析上的歧義。
function foo () {

}

{
foo: foo()
}

複製代碼

上面代碼像是建立了一個對象可是沒有變量接收,可是其實是{}表明了一個代碼塊,而foo:在正常代碼中寫法顯得奇怪可是沒有報錯,是由於這裏有個咱們不經常使用的label代碼標籤。微信小程序

  • 上面代碼塊中的邏輯爲「定義了一個名爲foo的語句foo()

代碼標籤在循環中的做用

  • break continue跳出嵌套循環
for (var i = 0; i < 3; i++) {
  for (var j = 0; j < 3; j++) {
    if (i === j) {
      break;
    }
    console.log(i,j)
  }
}

// 1 0
複製代碼
foo: for (var i = 0; i < 2; i++) {
  for (var j = 0; j < 2; j++) {
    if (i === j) {
      break foo; // 表示跳出標籤爲foo的循環,即外層循環
    }
    console.log(i,j)
  }
}
// 沒有打印任何i,j
複製代碼

分號問題

自動分號

  • Automatic Semicolon Insertion,ASI,自動分號插入。
  • JavaScript解析器中發現代碼行可能由於缺乏分號而致使錯誤,就會在代碼行末尾與換行符之間沒有其餘內容的狀況下(空格和註釋除外)自動補上分號。

糾錯機制

  • ASI是一種糾錯機制,如今有些時候被用於語法簡潔。
  • 在以前學習ES6時,有聽到一種說法是「es6中建議省略沒必要要的分號」,因而在學習es6以後,都習慣性的不加分號了。
  • 在瞭解了這個規範以後,對於加不加分號有了新的認識:這不是一個代碼美觀問題,而是一個語法規則問題。

異議

json語法在控制檯直接輸入的報錯解釋

書中的說法: 如下代碼在控制檯直接輸入會報錯,由於{..}被解析成代碼塊,foo被解析成標籤,而標籤不能帶有引號

> {
  "a": 20
  }
複製代碼

實際的結果:

chrome中會解析成建立了一個對象和{a:20}相同。

如下兩種{}的運行結果 報錯:

> ;{
    "a": 20
  }
複製代碼

不報錯:

> ;{
    a: 20
  }
< 20
複製代碼

強制類型轉換的問題

[] + {} // "[object Object]"
{} + [] // 0
複製代碼

{} + [] 中{}被視爲代碼塊,空代碼塊被強制類型轉換後的值怎麼肯定的不太明確。 但能夠測試空代碼塊的返回值是undefined

> eval("{}")
< undefined

> ;{}
< undefined
複製代碼

  • 做者簡介:葉茂,蘆葦科技web前端開發工程師,表明做品:口紅挑戰網紅小遊戲、服務端渲染官網。擅長網站建設、公衆號開發、微信小程序開發、小遊戲、公衆號開發,專一於前端領域框架、交互設計、圖像繪製、數據分析等研究。 一塊兒並肩做戰: yemao@talkmoney.cn 訪問 www.talkmoney.cn 瞭解更多
相關文章
相關標籤/搜索