ES7中有一項(xiàng) do表達(dá)式
提案千贯,類似
var a , b;
a = do {
if(true){
b = 4 + 38;
}
};
a; // 42
其目的是將語句當(dāng)作表達(dá)式來處理恰梢,從而不需要將語句封裝為函數(shù)再調(diào)用return 來返回值捎迫。
5.1.2 表達(dá)式副作用
最常見的有副作用的表達(dá)式是函數(shù)調(diào)用:
function foo() {
a = a + 1;
}
var a = 1;
foo(); // 結(jié)果值: undefined 匠抗。副作用: a 的值被改變
可使用统刮,語句系列逗號(hào)運(yùn)算符將多個(gè)獨(dú)立的表達(dá)式語句串聯(lián)成一個(gè)語句:
var a = 42, b;
b = ( a++, a );
a; // 43
b; // 43
a++, a 中第二個(gè)表達(dá)式a在a++之后執(zhí)行紊遵,結(jié)果為43,并被賦值給b侥蒙。
var a, b, c;
a = b = c = 42;
鏈?zhǔn)劫x值常常被誤用暗膜,例如var a = b = 42; 看似和前面的例子差不多,實(shí)則不然鞭衩。如果變量b沒有在作用域中象var b 這樣聲明過学搜,則var a = b =c = 42 不會(huì)對(duì)變量b進(jìn)行聲明娃善。在嚴(yán)格模式中會(huì)產(chǎn)生錯(cuò)誤,或者會(huì)無意中創(chuàng)建一個(gè)全局變量瑞佩。
5.1.3 上下文規(guī)則
- 大括號(hào)
(1)對(duì)象常量
// 假定bar() 已定義
var a = {
foo: bar()
}
{..}被賦值給a,因?yàn)樗且粋€(gè)對(duì)象常量聚磺。
(2)標(biāo)簽
如果將上例中的 var a = 去掉會(huì)發(fā)生什么情況呢?
{
foo: bar()
}
{..}在這里只是一個(gè)普通的代碼塊炬丸。語法是完全合法的瘫寝,特別是和let在一起時(shí)非常有用。
但foo: bar() 這樣奇怪的語法為什么也合法呢稠炬?
這里涉及JS中一個(gè)不為人知的特性焕阿,叫做"標(biāo)簽語句",foo是語句bar() 的標(biāo)簽(后面沒有;)
如果JS有g(shù)oto語句首启,理論上可使用goto foo跳轉(zhuǎn)到foo處執(zhí)行暮屡。但JS不支持goto。
然而JS通過標(biāo)簽跳轉(zhuǎn)能實(shí)現(xiàn)goto的部分功能闽坡。continue和break語句都可帶一個(gè)標(biāo)簽栽惶,因此能像goto那樣進(jìn)行跳轉(zhuǎn)。
// 標(biāo)簽為foo的循環(huán)
foo: fro ( var i = 0; i<4; i++) {
for(var j = 0; j<4; j++){
// 如果j和i相等疾嗅,繼續(xù)外層循環(huán)
if(j == i) {
// 跳轉(zhuǎn)到foo的下一個(gè)循環(huán)
continue foo;
}
// 跳過奇數(shù)結(jié)果
if( (j*i) % 2 == 1 ){
// 繼續(xù)內(nèi)層循環(huán)(沒有標(biāo)簽的)
continue;
}
console.log( i, j );
}
}
continue foo 并不是指“跳轉(zhuǎn)到標(biāo)簽foo所在位置繼續(xù)執(zhí)行”外厂,而是"執(zhí)行foo循環(huán)的下一輪循環(huán)"。
帶標(biāo)簽的循環(huán)跳轉(zhuǎn)一個(gè)更大的用處在于代承,和 break __ 一起使用可實(shí)現(xiàn)從內(nèi)層循環(huán)跳轉(zhuǎn)到外層循環(huán)汁蝶。
// 標(biāo)簽為foo的循環(huán)
foo: for( var i = 0; i < 4; i++){
for(var j=0; j<4; j++){
if( (i*j) >= 3){
console.log("stopping!", i, j);
break foo;
}
console.log(i, j);
}
}
標(biāo)簽也能用于非循環(huán)代碼塊,但只有break才可以论悴。我們可對(duì)帶標(biāo)簽的代碼塊使用break __掖棉,但是不能對(duì)帶標(biāo)簽的非循環(huán)代碼塊使用continue __,也不能對(duì)不帶標(biāo)簽的代碼塊使用break;
// 標(biāo)簽為bar的代碼塊
function foo(){
bar: {
console.log("Hello");
break bar;
console.log( "never runs" );
}
console.log( "world" );
}
foo();
// Hello
// World
- 對(duì)象解構(gòu)
function getData() {
return {
a: 42,
b: "foo"
}
}
var {a, b} = getData();
console.log(a, b); // 42 "foo"
{a, b} = ..就是ES6中的解構(gòu)賦值膀估,相當(dāng)于下面的代碼:
var res = getData();
var a = res.a;
var b = res.b;
{..}還可用作函數(shù)命名參數(shù)的對(duì)象解構(gòu)幔亥,方便隱式地用對(duì)象屬性賦值:
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'
})
5.2.1 短路
對(duì)&& 和 || 來說,如果從左邊的操作數(shù)能夠得出結(jié)果察纯,就可忽略右邊的操作數(shù)帕棉。我們將這種現(xiàn)象稱為"短路"。
function doSomething(opts){
if(opts.cache || primeCache()){
//..
}
}
5.5 函數(shù)參數(shù)
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