03 語(yǔ)法

ES7中有一項(xiàng) do表達(dá)式 提案,類似

var a , b;
a = do {
    if(true){
        b = 4 + 38;
    }
};
a; // 42

其目的是將語(yǔ)句當(dāng)作表達(dá)式來(lái)處理,從而不需要將語(yǔ)句封裝為函數(shù)再調(diào)用return 來(lái)返回值。

5.1.2 表達(dá)式副作用

最常見(jiàn)的有副作用的表達(dá)式是函數(shù)調(diào)用:

function foo() {
    a = a + 1;
}
var a = 1;
foo();   // 結(jié)果值: undefined 。副作用: a 的值被改變

可使用,語(yǔ)句系列逗號(hào)運(yùn)算符將多個(gè)獨(dú)立的表達(dá)式語(yǔ)句串聯(lián)成一個(gè)語(yǔ)句:

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沒(méi)有在作用域中象var b 這樣聲明過(guò),則var a = b =c = 42 不會(huì)對(duì)變量b進(jìn)行聲明。在嚴(yán)格模式中會(huì)產(chǎn)生錯(cuò)誤,或者會(huì)無(wú)意中創(chuàng)建一個(gè)全局變量。

5.1.3 上下文規(guī)則

  1. 大括號(hào)
    (1)對(duì)象常量
// 假定bar() 已定義
var a = {
    foo: bar()
}

{..}被賦值給a,因?yàn)樗且粋€(gè)對(duì)象常量。

(2)標(biāo)簽
如果將上例中的 var a = 去掉會(huì)發(fā)生什么情況呢?

{
        foo: bar()
    }  

{..}在這里只是一個(gè)普通的代碼塊。語(yǔ)法是完全合法的,特別是和let在一起時(shí)非常有用。

但foo: bar() 這樣奇怪的語(yǔ)法為什么也合法呢?

這里涉及JS中一個(gè)不為人知的特性,叫做"標(biāo)簽語(yǔ)句",foo是語(yǔ)句bar() 的標(biāo)簽(后面沒(méi)有;)

如果JS有g(shù)oto語(yǔ)句,理論上可使用goto foo跳轉(zhuǎn)到foo處執(zhí)行。但JS不支持goto。

然而JS通過(guò)標(biāo)簽跳轉(zhuǎn)能實(shí)現(xiàn)goto的部分功能。continue和break語(yǔ)句都可帶一個(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;
        }
        // 跳過(guò)奇數(shù)結(jié)果
        if( (j*i) % 2 == 1 ){
            // 繼續(xù)內(nèi)層循環(huán)(沒(méi)有標(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
  1. 對(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ì)&& 和 || 來(lái)說(shuō),如果從左邊的操作數(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
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容