Q1使用開發者工具,控制台,輸入一段js程式碼。點擊回車時發生了什麼事?
如何解釋下圖的輸出與報錯
##Q2除了變數宣告和定義時,有逗號時,點擊回車發生了什麼事?
如何解釋下圖的輸出與報錯
#Q3加上圓括號運算子之後,回車,發生了什麼事?
為什麼這裡,第一個 第三個,跟上面的結果不一樣
Q4逗號,圓括號(立即執行函數),回車,共同的效果如下
希望能在前面問題的基礎上,弄清楚
小白 強迫症提問,先謝謝大家! ###
ringa_lee2017-05-19 10:36:20
敲擊回車,控制台會使用頁面的 js 解析器執行輸入的程式碼,並把執行最後一條語句得到的回傳值顯示在控制台。
var a=1 // undefined
a=111 //111
111 // 111
原因是 var 語句的回傳值是 undefined
, a=111
这是一个赋值运算,赋值运算的返回值是a
。匿名function報錯這個解釋起來有點費勁。
js 中關於函數有兩個概念:函數宣告 和 函數表達式。
var a = function(){} // 函数表达式,(匿名函数表达式)
function b(){} // 函数声明
var c = function c(){} // 函数表达式(命名函数表达式)
// 旧IE不支持named function expression
由於函數宣告和命名函數表達式很像,js 引擎是怎麼區分 function
關鍵字後面接的到底是函數宣告還是函數表達式呢?答案是看當前的上下文語境。如果上下文情境是求值環境,那麼 function 就被認定為引出一個函數表達式,否則即認為是函數宣告。
Q1的這個報錯就是因為,目前上下文不是一個求值語境,function 被解析為函數聲明,報錯的Uncaught SyntaxError: Unexpected token (
意思是不可預期的左括號,很好理解,函數聲明需要一個函數名字,這裡沒有給出函數名稱就出現左括號,因此報語法錯報的是左括號這個位置。
,
逗號是 js 中的運算符,逗號運算子會依序執行逗號左右的表達式,傳回值是逗號右側的表達式的值。
1,function(){} // => function(){}
這個不報錯的原因就是因為,語境1,...
構成了一個求值上下文,因此後面的 function 被正確解析為函數表達式。
而反過來書寫報錯,是因為逗號運算子還沒有解析到,當前還不是一個求值語境,所以 function 被認作是函數宣告。至於為什麼不在解析到逗號後回溯,這個可能是考慮實現成本,左右操作數的運算子有很多,而且例如:
function a(){}
+“”
這種程式碼,你說是解析成命名函數表達式加上一個空字串,還是解析成函數宣告和一條語句呢?
因此,從現像上看,在判斷 function 關鍵字的時候,js 引擎只看當前的上下文語境,而不進行回溯。 (可能還有其他的潛在的問題導致不可能回溯)
()
括号在 js 中也是一种运算符,叫组运算符
,組運算子優先權最高,傳回值是括號內的表達式求值的結果。
(function(){})
构成了一个合法的表达式,而(var a=1)
报错是因为组运算符内只允许表达式,var a=1
是語句。
(0,function(){
console.log(1)
})() // log 1, 返回 undefined
(function(){
console.log(1)
}, 2)() // 报错,2不是函数
相信你已經明白了。
阿神2017-05-19 10:36:20
點選回車,<
后面的是返回值,变量声明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中语句
和表达式
的區別上面,弄懂了什麼是語句,什麼是表達式,上面的所有問題你都可以自己明白。
迷茫2017-05-19 10:36:20
自問自答,總結一下:
敲擊回車,控制台會使用頁面的 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標準參考教學-運算子