Blog

深入js-语句与表达式

time: 2018.12.24

1 背景

语句和表达式,是所有编程语言都会涉及到的一个知识点。

今天在看一个问题,下面代码执行结果是什么?为什么?

(function() {console.log('hello')})()


function() {console.log('hello')}()

为什么第二个执行就会报错? Uncaught SyntaxError: Unexpected token (
给出的答案是:

函数声明属于语句,括号属于表达式。
在js创建执行环境的时候,会对语句进行预编译,比如变量声明提升、函数声明提升,创建作用域链、AO、this;
但是它不会对表达式进行处理,表达式的执行是在创建好执行环境之后,运行代码时执行的,表达式的执行结果是要有返回值,但是语句却没有返回值。
所以在执行 function() {console.log('hello')}() 时,由于函数声明属于语句,不会有返回值,此刻 js 引擎会直接执行 () 表达式,但是括号内部没有内容,所以会报错;在执行 (function() {console.log('hello')})() 时,js 引擎在准备阶段,不会去处理表达式的内容,在执行阶段,(function() {console.log('hello')}) 括号表达式执行结果会返回一个函数,然后配合后一个括号,再次执行函数。

2 语句和表达式

javascript 的语句,不是表达式的都是语句,表达式要求执行某个运算,有返回值,大多数语言表达式的定义为

  1. 字面量表达式:1, 2, ‘abc’
  2. 一元表达式:!true
  3. 二元表达式:a + b
  4. 三元表达式:a>b?a:b
  5. 括号表达式:(function (){})()
  6. 函数调用

3 关键点

js引擎执行时机:

在为一段可执行代码创建执行环境的时候,会有一个代码预编译过程,在这个过程中会创建作用域链、AO、this,此处就存在变量提升了,也就是引擎会先扫描一遍代码。
在预编译结束之后,才开始正式执行,也就是执行逻辑代码、表达式。