前言

定义

语法(Grammer)与 句法(Syntax)的在JS中的区别就是语法包括句法,因此本文使用语法一词。

声明 & 表达式

许多人认为声明(statement)与表达式(expressions)是一回事,然而JS中,这两者之间的区别非常重要。

以英语为例,声明就是完整句子,表达式是短语,操作符是连词。貌似 声明∈表达式∈操作符?

var a = 3 * 6; // var a | a = 3*6 | 3*6 都是表达式? var | = | * 都是连词?
var b = a;
b; // b 虽然是个表达式,但同时可以是声明,而这种叫 ”表达式声明“

获取声明完成值

  1. 在REPL(Read Evaluate Print Loop)中,比如chrome的console,会打印出声明表达式的完成值
  2. eval( )
  3. do { } // ES7

表达式的副作用

  1. ++a
  2. delete
  3. a = b = c

上下文

声明与表达式在不同的上下文中是不一样的

各种“{ }”在不同位置表达式的意思也不相同

  1. 对象

    obj = { foo: bar()}

  2. 标签 + 代码块

    foo: { bar(); break foo}

  3. 对象解构 ( ES6 )

    var {a,b} = {a:1,c:3,b:2}; // a=>1 b=>2
    function foo({a,b,c}) {console.log(a,b,c)};
    foo({a:1,b:2,c:3});

操作符优先级(Operator Precedence)

第四章里已经讲过,JS中的 && 与 || 操作符的行为并不是简单的返回 true 或 false

419 && "turing"; //=> "turing"
419 ||  "turing"; //=> 419

是不是表现的很奇怪,不过这一章我们不关心返回值,而是关于多个操作符并列使用的优先级

详细的介绍请直接查询 MDN

这里说一些特性

短路(short circuited)

短路的意思就是当使用 && 或 || 进行判断时,如果操作符左侧表达式的返回值已经能确定结果,那么右边的表达式就不会被处理了。

true || 3*6; //=> true
false && 1+2; //=> false

短路的作用

1.防止错误抛出

if (obj && obj.foo) { ...do something } 如果obj未声明,使用obj.foo会直接抛出错误的

2.减轻工作负担

if (somevar || foo()) {...} 这里如果somevar已经存在了,那么就不用再执行foo了

那么问题来了,既然有优先级,我们需要让JS自动处理,还是用()来把优先级提升呢?这个问题肯定要让各路大神撕到起飞。建议就是合理使用,比如 a && b && c;这种看起来直观的就没必要使用(),而像a ? ( b ? c : d ) : e; 这种容易引发歧义的还是用()比较让人容易理解。