语句和表达式
1、ES7规范有一项"do表达式"提案,类似下面这样。do{}表达式执行一个代码块(包含一个或多个语句),并且返回其中最后一个语句的返回值
,然后赋值给变量a。
var a,b;
a = do{
if(true){
b = 4 + 32;
}
}
a // 42
复制代码
2、可以使用,语句系列逗号运算符
将多个独立的表达式语句串联成一个语句。(a++,a中第二个表达式a在a++之后执行,结果为43,并被赋值给b)
var a = 42,b;
b = (a++,a)
a // 43
b // 43
复制代码
3、delete运算符可以删除对象中的属性和数组中的单元。(如果操作成功,delete返回true,否则返回false)
var obj = {
a:42
}
obj.a // 42
delete obj.a // true
obj.a //undefined
复制代码
4、使用var a = b = 42,不会对变量进行声明,在严格模式中这样会产生错误,或者会无意中创建一个全局变量(b)。
5、代码块
[] + {} // "[object Object]"
{} + [] // 0
复制代码
第一行代码中,[]被强制类型转换为"",而{}会被强制类型转换为"[object Object]"
第二行代码中,{}被当做一个独立的空代码块,代码块结尾不需要分号,最后+[]将[]显示强制类型转换为0。
6、事实上Javascript没有else if,但if和else只包含单条语句的时候可以省略代码块的{}
运算符优先级
1、,
运算符的优先级比=
低,用,来连接一系列语句的时候,它的优先级最低
,其他操作数的优先级都比它高。
var a = 42,b;
b = (a++,a)
a // 43
b // 43
var a = 42,b;
b = a++,a;
a // 43
b // 42
复制代码
2、&&运算符的优先级高于=
。如果不加括号的话,就会执行作(str && matches)= str.match。这样会出错,由于(str && matches)的结果是一个undefined,因此它不能出现在=运算符的左边。
if(str && (matches = str.match(/[aeiou]/g))){
}
复制代码
3、&&运算符先于||执行
,而且执行顺序并非我们所设想的从左到右。
false && true || true // true
(false && true) || true // true
true || false && false // true
(true || false) && false // false
true || (false && false) // true
复制代码
4、&&运算符的优先级高于||,而||的优先级又高于?:
a && b || c ? c || b ? a : c && b : a
等于
(a && b || c) ? (c || b) ? a : (c && b) : a
复制代码
5、?:是右关联的。
a ? b : c ? d : e
等于
a ? b : (c ? d : e)
复制代码
6、暂时性死区
{
a = 2; // ReferenceError 变量a初始化之前赋值会抛出错误
let a;
}
// 对未声明的变量使用typeof不会产生错误
{
typeof a; // undefined
typeof b; // ReferenceError
let b;
}
复制代码
函数参数
1、在ES6中,如果参数被省略
或者值为undefined
,则取该参数的默认值。
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
复制代码
2、如果向函数传递undefined,则arguments数组中会出现一个值为undefined的单元,而不是默认值。
function foo(a = 42,b = a + 1) {
console.log(
arguments.length,a,b,
arguments[0],arguments[1]
)
}
foo() // 0 42 43 undefined undefined
foo(10) // 1 10 11 10 undefined
foo(10,undefined) // 2 10 11 10 undefined
foo(10,null) // 2 10 null 10 null
复制代码
3、向函数传递参数时,arguments数组中的对应单元会和命名参数建立关联以得到相同的值,不传递不建立关联(严格模式没有建立关联)
function foo(a){
a = 42;
console.log(arguments[0])
}
foo(2) // 42 (linked)
foo() // undefined(not linked)
function foo(a){
"use strict"
a = 42;
console.log(arguments[0])
}
foo(2) // 2 (not linked)
foo() // undefined(not linked)
复制代码
try...finally
1、finally中的代码总是会在try之后执行,如果有catch的话则在catch之后执行,也可以将finally中的代码看作是一个回调函数,最后一定被调用。
function foo() {
try{
return 42
}
finally {
console.log('Hello')
}
console.log('never runs')
}
console.log(foo())
// Hello
// 42
function foo() {
try{
throw 42
}
finally {
console.log('Hello')
}
console.log('never runs')
}
console.log(foo())
// Hello
// Uncaught Exception:42
function foo() {
try{
return 42
}
finally {
throw "Oops"
}
console.log('never runs')
}
console.log(foo())
// Uncaught Exception:Oops
复制代码
2、finally中的return会覆盖try和catch中的return的返回值。
function foo(){
try{
return 42;
}
finally{
// 没有返回语句,所以没有覆盖
}
}
function bar() {
try{
return 42;
}
finally{
return;
}
}
function baz() {
try{
return 42;
}
finally{
return "Hello";
}
}
foo() // 42
bar() // undefined
baz() // Hello
复制代码
switch
1、a和case表达式的匹配算法与===相同。
var a = '42'
switch(true){
case a == 10 :
break;
case a == 42:
break;
default:
}
复制代码
2、尽管可以使用==,但switch中true和true之间仍然是严格相等比较。即如果case表达式的结果为真值,但不是严格意义上的true,则条件不成立。
var a = 'hello world'
var b = 10;
switch(true){
case (a || b == 10): // 结果为'hello world' 不会执行这里
break; // 永远执行不到这里
default:
}
复制代码
转载于:https://juejin.im/post/5d08fc1051882572d746fb03