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标准参考教程——运算符