1. 语句和表达式

1.1 语句的结果值

语句都有一个结果值,以赋值表达式b = a为例,其结果值是赋给b的值,但规范定义var的结果值为undefined
代码块的结果值会返回最后一个语句的结果值。利用这个特性可以对代码做一些优化操作,如下所示:

  1. function vowels(str) {
  2. var matches
  3. if (str) {
  4. matches = str.match(/[aeiou]/g)
  5. if (matches) {
  6. return matches
  7. }
  8. }
  9. }

以上代码可以利用赋值运算符的结果值合并代码,优化后的结果如下:

  1. function vowels(str) {
  2. var matches
  3. if(str && (matches = str.match(/[aeiou]/g))) {
  4. return matches
  5. }
  6. }

1.2 上下文规则

在JavaScript语法规则中,有时候同样的语法在不同情况下有不同的解释。

1.2.1 大括号

  1. //对象字面量
  2. var a = {
  3. foo: bar()
  4. }
  5. //直接写对象字面量,{}会被解析成一个代码块,而foo被解析为bar()的标签
  6. {
  7. foo: bar()
  8. }

1.2.2 代码块

  1. //[]被解析为字符串"" {}被解析为[object object]
  2. [] + {} //[object object]
  3. //{}被解析为一个空代码块,+[]会将[]强制转换为数字也就是0
  4. {} + [] //0

1.3 运算符优先级

&&优先级高于|| ,||优先级高于三元运算符? :

1.4 自动分号

JavaScript会自动为代码行补上缺失的分号,即自动分号插入(Automatic Semicolon Insertion,ASI)。_特别注意:ASI会在break continue return yield等关键字后边补上分号。

  1. //ASI会在return后边补上分号,导致之后的语句 a *= 2不会执行
  2. function foo(a) {
  3. if(!a) return
  4. a *= 2
  5. }

1.5 try .. finally执行顺序

1.5.1 try中return语句返回

  1. function foo() {
  2. try {
  3. return 42
  4. }
  5. finally {
  6. console.log('hello')
  7. }
  8. console.log('never runs')
  9. }
  10. console.log(foo())
  11. //hello
  12. //42

分析:return 42先执行,并将foo函数的返回值设为42,然后执行finally,最后foo执行完毕,console.log打印函数返回值

1.5.2 如果finally中抛异常

如果finally中抛异常那么函数就会终止,如果此前try中有return设置了返回值,则该值会被抛弃

1.5.3 finally中有返回值

finally中的return会覆盖try和catch中的返回值