语法
语句表达式
句子是完整表达某个意思的一组词,由一个或多个短语组成,他们之间由标点符号或者连接词连接起来。
语句相当于句子,表达式相当于短语,运算符则相当于标点符号和连接词。
JavaScript 中表达式可以返回一个结果值。
var a = 3 * 6;
var b = a;
b;
var a = 3 * 6; var b = a; 声明语句,因为它声明了语句
a = 3 * 6; b = a; 表达式语句
语句的结果值
表达式的副作用
var a = 42; var b = a++; a; // 43 b; // 42
a++ 首先返回变量 a 的当前值 42 (在将值赋给b),然后将 a 的值加 1;
++ 在前面时,如++a, 它的副作用将(a递增)产生在表达式返回结果之前而 a++ 的副作用则产生在之后。
++a++ 会产生 ReferenceError错误
var a = 42; var b = (a++); a; // 43 b; // 42
可以使用语句系列运算符将多个独立的表达式语句串联成一个语句:
var a = 42,b; b = (a++,a) a; // 43 b; // 43
delete 运算符用来删除对象中属性和数组中的元素。
var obj = { a:42 }; obj.a; // 42 delete obj.a; // true obj.a; // undefined function vowels(str){ var matches; if(str) { // 提取所有元音字母 matches = str.match(/[aeiou]/g); if(matches) { return matches; } } } vowels("Hello World"); // ["e","o","o"]
利用赋值语句的副作用将两个if 语句合二为一
function vomels (str){ var matches; // 提取所有元素字母 if(str && (matches = str.match(/[aeiou]/g))){ return matches; } } vowels("Hello World"); // ["e","o","o"]
上下文规则
1.大括号
对象常量
// 假定 函数 bar() 已经定义
var a = { foo: bar() }
标签
// 假定 函数 bar() 已经定义
{
foo: bar()
}
代码块
[] + {}; // "[object Object]" {} + []; // 0
对象解构
function getData() { // .. return { a: 42, b: "foo" }; } var { a , b } = getData(); console.log(a,b); // 42 "foo" {...} 还可以用作函数命名参数的对象解构,方便隐式地对象属性赋值。 function foo({a,b,c}){ // 不在需要这样: // var a = obj.a, b = obj.b, c = obj.c console.log(a,b,c) } foo({ c: [1,2,3], a: 42, b:"foo" }); // 42 "foo" [1,2,3]
运算符优先级
var a = 42; var b = "foo"; a && b; // "foo" a || b; // 42
短路
对于 && 和 || 来说,如果从左边的操作数能够得出结果,就可以忽略右边的操作数,我们将这种现象称为短路。
a && b || c ? c || b ? a : c && b : a
因为 && 运算符的优先级高于 ||, 而 || 的优先级又高于 ? :。
(a && b || c) ? (c || b) ? a : (c && b) : a
关联
运算符的关联不是从左到右就是从右到左,这取决于组合是从左开始还是从右开始。
var a = foo() && bar();
先执行 foo() 遵循从左到右的执行循序
var a , b , c; a = b = c = 42;
实际上是这样处理的 a = (b = ( c = 42))
var a = 42; var b = "foo"; var c = false; var d = a && b || c ? c || b ? a : c && b : a; d; // 42 ((a && b) || c) ? ((c || b) ? a : (c && b)) : a
现在来逐一执行
1.(a && b) 结果为 “foo”.
2."foo" || c 结果为 “foo”.
3,第一个 ? 中 “foo” 为真。
4.(c || b) 结果为 "foo".
5.第二个 ? 中, “foo” 为真值。
6.a 的值为 42
错误
在编译阶段发生错误叫做早期错误,语法错误是早期错误的一种,使用 try..catch来捕获
语法错误浏览器一般报 SyntaxError
提前使用变量
暂时性死区 TDZ
let 作用域块
{ a = 2; // ReferenceError let a; }
函数参数
function foo(a = 42, b = a + 1 ){ console.log(a,b) } foo(); // 42 43 foo(undefined); // 42 43 foo(5); // 5 6 foo(void 0, 7); // 42 7 foo(null ) // null 1
try.. finally
finally中的代码总会在try 之后执行,如果有catch 的话则在catch 之后执行。
可以将finally 中的代码看做一个回调函数,总是在最后一个执行。
switch
可以把它看做 if..else if.. else 的简化版。
switch (a) { case 2: // 执行一些代码 back; case 42: // 执行一些代码 back; default: // 执行一些代码 }
混合环境 JavaScript
动态创建script,标签,将其加入到页面的DOM 中。
var greeting = "Hello World"; var el = document.createElement("script"); el.text = "function foo(){ alert(greeting); setTimeout(foo,1000)}"; document.body.appendChild(el);
如果将el.src 的值设置为 URL,就可通过<script src="">
保留字:
保留字不能将它用作变量名: 保留字有四类:
“关键字” “预留关键字” “null 常量” “true/false”