1. 语句和表达式
1.1 语句的结果值
语句都有一个结果值,以赋值表达式b = a为例,其结果值是赋给b的值,但规范定义var的结果值为undefined
代码块的结果值会返回最后一个语句的结果值。利用这个特性可以对代码做一些优化操作,如下所示:
function vowels(str) {
var matches
if (str) {
matches = str.match(/[aeiou]/g)
if (matches) {
return matches
}
}
}
以上代码可以利用赋值运算符的结果值合并代码,优化后的结果如下:
function vowels(str) {
var matches
if(str && (matches = str.match(/[aeiou]/g))) {
return matches
}
}
1.2 上下文规则
在JavaScript语法规则中,有时候同样的语法在不同情况下有不同的解释。
1.2.1 大括号
//对象字面量
var a = {
foo: bar()
}
//直接写对象字面量,{}会被解析成一个代码块,而foo被解析为bar()的标签
{
foo: bar()
}
1.2.2 代码块
//[]被解析为字符串"" {}被解析为[object object]
[] + {} //[object object]
//{}被解析为一个空代码块,+[]会将[]强制转换为数字也就是0
{} + [] //0
1.3 运算符优先级
&&优先级高于|| ,||优先级高于三元运算符? :
1.4 自动分号
JavaScript会自动为代码行补上缺失的分号,即自动分号插入(Automatic Semicolon Insertion,ASI)。_特别注意:ASI会在break continue return yield等关键字后边补上分号。
//ASI会在return后边补上分号,导致之后的语句 a *= 2不会执行
function foo(a) {
if(!a) return
a *= 2
}
1.5 try .. finally执行顺序
1.5.1 try中return语句返回
function foo() {
try {
return 42
}
finally {
console.log('hello')
}
console.log('never runs')
}
console.log(foo())
//hello
//42
分析:return 42先执行,并将foo函数的返回值设为42,然后执行finally,最后foo执行完毕,console.log打印函数返回值
1.5.2 如果finally中抛异常
如果finally中抛异常那么函数就会终止,如果此前try中有return设置了返回值,则该值会被抛弃
1.5.3 finally中有返回值
finally中的return会覆盖try和catch中的返回值