Q1使用開發者工具,控制台,輸入一段js程式碼。點擊回車時發生了什麼事? 如何解釋下圖的輸出與報錯
##Q2除了變數宣告和定義時,有逗號時,點擊回車發生了什麼事? 如何解釋下圖的輸出與報錯
#Q3加上圓括號運算子之後,回車,發生了什麼事? 為什麼這裡,第一個 第三個,跟上面的結果不一樣
Q4逗號,圓括號(立即執行函數),回車,共同的效果如下希望能在前面問題的基礎上,弄清楚
走同样的路,发现不同的人生
敲擊回車,控制台會使用頁面的 js 解析器執行輸入的程式碼,並把執行最後一條語句得到的回傳值顯示在控制台。
var a=1 // undefined a=111 //111 111 // 111
原因是 var 語句的回傳值是 undefined, a=111这是一个赋值运算,赋值运算的返回值是a。匿名function報錯這個解釋起來有點費勁。
undefined
a=111
a
js 中關於函數有兩個概念:函數宣告 和 函數表達式。
var a = function(){} // 函数表达式,(匿名函数表达式) function b(){} // 函数声明 var c = function c(){} // 函数表达式(命名函数表达式) // 旧IE不支持named function expression
由於函數宣告和命名函數表達式很像,js 引擎是怎麼區分 function 關鍵字後面接的到底是函數宣告還是函數表達式呢?答案是看當前的上下文語境。如果上下文情境是求值環境,那麼 function 就被認定為引出一個函數表達式,否則即認為是函數宣告。
function
Q1的這個報錯就是因為,目前上下文不是一個求值語境,function 被解析為函數聲明,報錯的Uncaught SyntaxError: Unexpected token (意思是不可預期的左括號,很好理解,函數聲明需要一個函數名字,這裡沒有給出函數名稱就出現左括號,因此報語法錯報的是左括號這個位置。
Uncaught SyntaxError: Unexpected token (
, 逗號是 js 中的運算符,逗號運算子會依序執行逗號左右的表達式,傳回值是逗號右側的表達式的值。
,
1,function(){} // => function(){}
這個不報錯的原因就是因為,語境1,...構成了一個求值上下文,因此後面的 function 被正確解析為函數表達式。
1,...
而反過來書寫報錯,是因為逗號運算子還沒有解析到,當前還不是一個求值語境,所以 function 被認作是函數宣告。至於為什麼不在解析到逗號後回溯,這個可能是考慮實現成本,左右操作數的運算子有很多,而且例如:
function a(){} +“”
這種程式碼,你說是解析成命名函數表達式加上一個空字串,還是解析成函數宣告和一條語句呢?
因此,從現像上看,在判斷 function 關鍵字的時候,js 引擎只看當前的上下文語境,而不進行回溯。 (可能還有其他的潛在的問題導致不可能回溯)
()括号在 js 中也是一种运算符,叫组运算符,組運算子優先權最高,傳回值是括號內的表達式求值的結果。
()
组运算符
(function(){})构成了一个合法的表达式,而(var a=1)报错是因为组运算符内只允许表达式,var a=1是語句。
(function(){})
(var a=1)
var a=1
(0,function(){ console.log(1) })() // log 1, 返回 undefined (function(){ console.log(1) }, 2)() // 报错,2不是函数
相信你已經明白了。
點選回車,<后面的是返回值,变量声明var a = 1是沒有回傳值的,所以是undefined,直接變數+回車,等於輸出這個變數。
<
var a = 1
','是一個運算符,在c語言中,,是優先級最低的操作符(推測js應該也是),它的作用是先計算','前面的式子,然後在計算','後面的式子,最終結果回傳','後面的式子。
這一點確定了,你的問題裡面大部分就能解決了。
最後說一點,var a = 1根据词法解析,其实等同于var a; a = 1这两句。而js里面()又比较特殊,放表达式是没问题的,比如(a = 1)或者(a ? b : c)這種就沒問題。
var a; a = 1
(a = 1)
(a ? b : c)
問題出在(var a)是错的,因为这不是表达式,不能括起来。同样的(if (a) {b} else {c})寫出來也是錯的,這種就要想辦法寫成上面用三目運算子才能括起來嘍。
(var a)
(if (a) {b} else {c})
其實題主的問題主要在js中语句和表达式的區別上面,弄懂了什麼是語句,什麼是表達式,上面的所有問題你都可以自己明白。
语句
表达式
自問自答,總結一下:
變數聲明和函數聲明,不傳回任何值,或傳回undifined
JS判定 function 關鍵字後面接的到底是函數宣告還是函數表達式,看上文語境。
逗號操作符:在一個語句中執行多個操作。用於賦值時,逗號運算子傳回表達式中的最後一項。 ————紅寶書有
var num =(1,2,3,0) //num的值为0
圓括號不是運算符,而是一種語法結構。
var x = 1; (x) //迷惑 var x = 1; (x) = 2;//返回2,没有报错,所以“圆括号不是运算符,而是一种语法结构。”
它一共有两种用法: 一种是把表达式放在圆括号之中,提升运算的优先级; 另一种是跟在函数的后面,作用是调用函数。
注意:運算子圓括號之中,只能放置表達式,如果將語句放在圓括號之中,就會報錯。
立即執行函數()()第一個括號裡要是function,具體是(結合Q3)函數表達式,匿名表達式、命名表達式都可以
以上參考:will回答 和阮一峰的JS標準參考教學-運算子
Q1
敲擊回車,控制台會使用頁面的 js 解析器執行輸入的程式碼,並把執行最後一條語句得到的回傳值顯示在控制台。
原因是 var 語句的回傳值是
undefined
,a=111
这是一个赋值运算,赋值运算的返回值是a
。匿名function報錯這個解釋起來有點費勁。js 中關於函數有兩個概念:函數宣告 和 函數表達式。
由於函數宣告和命名函數表達式很像,js 引擎是怎麼區分
function
關鍵字後面接的到底是函數宣告還是函數表達式呢?答案是看當前的上下文語境。如果上下文情境是求值環境,那麼 function 就被認定為引出一個函數表達式,否則即認為是函數宣告。Q1的這個報錯就是因為,目前上下文不是一個求值語境,function 被解析為函數聲明,報錯的
Uncaught SyntaxError: Unexpected token (
意思是不可預期的左括號,很好理解,函數聲明需要一個函數名字,這裡沒有給出函數名稱就出現左括號,因此報語法錯報的是左括號這個位置。Q2
,
逗號是 js 中的運算符,逗號運算子會依序執行逗號左右的表達式,傳回值是逗號右側的表達式的值。這個不報錯的原因就是因為,語境
1,...
構成了一個求值上下文,因此後面的 function 被正確解析為函數表達式。而反過來書寫報錯,是因為逗號運算子還沒有解析到,當前還不是一個求值語境,所以 function 被認作是函數宣告。至於為什麼不在解析到逗號後回溯,這個可能是考慮實現成本,左右操作數的運算子有很多,而且例如:
這種程式碼,你說是解析成命名函數表達式加上一個空字串,還是解析成函數宣告和一條語句呢?
因此,從現像上看,在判斷 function 關鍵字的時候,js 引擎只看當前的上下文語境,而不進行回溯。 (可能還有其他的潛在的問題導致不可能回溯)
Q3
()
括号在 js 中也是一种运算符,叫组运算符
,組運算子優先權最高,傳回值是括號內的表達式求值的結果。(function(){})
构成了一个合法的表达式,而(var a=1)
报错是因为组运算符内只允许表达式,var a=1
是語句。Q4
相信你已經明白了。
點選回車,
<
后面的是返回值,变量声明var a = 1
是沒有回傳值的,所以是undefined,直接變數+回車,等於輸出這個變數。','是一個運算符,在c語言中,
,
是優先級最低的操作符(推測js應該也是),它的作用是先計算','前面的式子,然後在計算','後面的式子,最終結果回傳','後面的式子。這一點確定了,你的問題裡面大部分就能解決了。
最後說一點,
var a = 1
根据词法解析,其实等同于var a; a = 1
这两句。而js里面()
又比较特殊,放表达式是没问题的,比如(a = 1)
或者(a ? b : c)
這種就沒問題。問題出在
(var a)
是错的,因为这不是表达式,不能括起来。同样的(if (a) {b} else {c})
寫出來也是錯的,這種就要想辦法寫成上面用三目運算子才能括起來嘍。其實題主的問題主要在js中
语句
和表达式
的區別上面,弄懂了什麼是語句,什麼是表達式,上面的所有問題你都可以自己明白。自問自答,總結一下:
Q1
敲擊回車,控制台會使用頁面的 js 解析器執行輸入的程式碼,並把執行最後一條語句得到的回傳值顯示在控制台。
變數聲明和函數聲明,不傳回任何值,或傳回undifined
JS判定 function 關鍵字後面接的到底是函數宣告還是函數表達式,看上文語境。
Q2
逗號操作符:在一個語句中執行多個操作。用於賦值時,逗號運算子傳回表達式中的最後一項。 ————紅寶書有
Q3
圓括號不是運算符,而是一種語法結構。
注意:運算子圓括號之中,只能放置表達式,如果將語句放在圓括號之中,就會報錯。
Q4
立即執行函數()()
第一個括號裡要是function,具體是(結合Q3)函數表達式,匿名表達式、命名表達式都可以
以上參考:will回答 和阮一峰的JS標準參考教學-運算子