日韩久久久精品,亚洲精品久久久久久久久久久,亚洲欧美一区二区三区国产精品 ,一区二区福利

Javascript的聲明

系統(tǒng) 2805 0
Quiz

?

下面Javascript代碼為什么能運(yùn)行?

      
        hello();


      
      
        function
      
      
         hello(){
    alert(
      
      "Hello, world!"
      
        );
}
      
    

但對(duì)于C,這么寫會(huì)報(bào)錯(cuò):

      #include 
      
        "
      
      
        stdio.h
      
      
        "
      
      
        void
      
      
         main(){
    hello();
}


      
      
        void
      
      
         hello(){
    printf(
      
      
        "
      
      
        Hello, world\n
      
      
        "
      
      
        );
}
      
    

由于hello沒(méi)有被預(yù)先聲明,代碼“hello()”被認(rèn)為是隱式聲明,而隱式聲明返回類型是int,所以提示hello類型錯(cuò)誤。

通過(guò)預(yù)先聲明或者將main函數(shù)放在hello函數(shù)的后面可以很容易解決這個(gè)問(wèn)題。

那么對(duì)于Javascript卻能運(yùn)行,這代表了什么呢?

?

被提升的聲明

Javascript引擎會(huì)先對(duì)代碼解釋,將聲明提升,然后再執(zhí)行。例如為了判斷一個(gè)變量定義與否,如果我們?nèi)绱藢懯菚?huì)出引用錯(cuò)誤的:

      
        if
      
      (someVar ===
      
         undefined){
    alert(
      
      "someVar未定義"
      
        );
}
      
    

但如果這樣卻不會(huì)出錯(cuò):

      
        if
      
      (someVar ===
      
         undefined){
    
      
      
        var
      
      
         someVar = 1;
    alert(
      
      "someVar未定義"
      
        );
}
      
    

可見(jiàn)聲明被提升了,但只有聲明被提升了,因?yàn)閟omeVar依然等于undefined,而不是1。

值得一提的是,這樣子寫也會(huì)報(bào)錯(cuò):

      
        if
      
      (someVar ===
      
         undefined){
    someVar 
      
      = 1
      
        ;
    alert(
      
      "someVar未定義"
      
        );
}
      
    

這證明在解釋階段,隱式聲明是沒(méi)有作用的!而且為了讓代碼邏輯清晰,還是用顯式聲明吧!

?

chrome瀏覽器的詭異現(xiàn)象

?chrome瀏覽器(至少在本文簽寫時(shí)的最新版本 22.0.1229.94 m依然是如此 )有個(gè)詭異的現(xiàn)象:

      
        var
      
       name = 20
      
        ;
alert(
      
      
        typeof
      
      (name));    
      
        //
      
      
        string
      
      
name += 12
      
        ;
alert(name);    
      
      
        //
      
      
        2012
      
    

所以請(qǐng)不要把name定義為除字符串的其他類型,當(dāng)然可以的話也盡量避免使用這個(gè)全局變量吧。

?

函數(shù)的兩種創(chuàng)建方式

函數(shù)申明:

function ?函數(shù)名? ( 參數(shù) 可選 ){ ?函數(shù)體 ? }

函數(shù)表達(dá)式:

function 函數(shù)名 可選 ?(參數(shù) 可選 ){?函數(shù)體 ? }

Syntax
FunctionDeclaration :
function Identifier ( FormalParameterList opt ) { FunctionBody }
FunctionExpression :
function Identifier opt ?( FormalParameterListopt ) { FunctionBody }

—— Standard ECMA-262 ECMAScript Language Specification? ?. ECMA

為什么函數(shù)要分聲明( Function Declaration)和表達(dá)式( Function Expression)呢?

譯注:實(shí)際上FunctionDeclaration和FunctionExpression都是函數(shù)產(chǎn)生的語(yǔ)法,這和一般編程語(yǔ)言中函數(shù)聲明只是定義接受參數(shù)數(shù)量及類型與返回值類型不太相同。或者說(shuō),這根本不是字面意義上的函數(shù)聲明。我們可以理解對(duì)于Javascript的函數(shù)聲明(FunctionDeclaration)其實(shí)是聲明式(即需要提升的)函數(shù)產(chǎn)生語(yǔ)法,而函數(shù)表達(dá)式(FunctionExpression)則是表達(dá)式式(即執(zhí)行時(shí)產(chǎn)生)函數(shù)產(chǎn)生語(yǔ)法。

—— WhiteSnow

主要為了區(qū)分函數(shù)的創(chuàng)建是否需要被提升,如果是函數(shù)聲明就需要被提升創(chuàng)建,但如果是表達(dá)式,那么可以在執(zhí)行時(shí)再創(chuàng)建。這樣是很必要的,比如我們可以利用表達(dá)式動(dòng)態(tài)定義函數(shù):

      
        var
      
      
         foo;


      
      
        if
      
      
        (Condition){
    foo 
      
      = 
      
        function
      
      
        (){
        
      
      
        //
      
      
        do something
      
      
            }
}
      
      
        else
      
      
        {
    foo 
      
      = 
      
        function
      
      
        (){
        
      
      
        //
      
      
        do anything else
      
      
            }
}
      
    

再比如對(duì)于匿名函數(shù):

      (
      
        function
      
      
        (){
    
      
      
        //
      
      
        do something
      
      
})();
    

聲明提升也沒(méi)什么意義,因?yàn)樗粫?huì)在別的地方被引用。

?

如何判斷函數(shù)聲明與函數(shù)表達(dá)式

  • 匿名函數(shù)必然是函數(shù)表達(dá)式
  • 如果有名字的函數(shù)作為賦值表達(dá)式的一部分那么他也是一個(gè)表達(dá)式
  • 如果有名字的函數(shù)被括號(hào)“()”括住,那么他也是一個(gè)表達(dá)式

本文不準(zhǔn)備深入命名函數(shù)表達(dá)式(named function expressions),具體可參見(jiàn)參考文獻(xiàn),不過(guò)一般應(yīng)當(dāng)避免命名函數(shù)表達(dá)式的使用,因?yàn)榇蟛糠止δ芏伎梢杂媚涿瘮?shù)找到替代方案,或者說(shuō)實(shí)際使用中不必考慮命名函數(shù)表達(dá)式。

?

匿名函數(shù)立刻執(zhí)行

我們經(jīng)常希望匿名函數(shù)定義好后立刻執(zhí)行,但這么寫會(huì)拋出語(yǔ)法錯(cuò)誤:

      
        function
      
      
        (){
    alert(
      
      1
      
        );
}();
      
    

正確寫法如下。

  • 聲明一個(gè)函數(shù)對(duì)象,然后執(zhí)行它:
      (
      
        function
      
      
        (){
    alert(
      
      1
      
        );
})();
      
    
  • 用括號(hào)強(qiáng)制執(zhí)行:
      (
      
        function
      
      
        (){
    alert(
      
      1
      
        );
}());
      
    
  • 使用void操作符:
      
        void
      
      
        function
      
      
        (){
    alert(
      
      1
      
        );
}();
      
    

?

總結(jié)

  • Javascript中聲明會(huì)被提升;
  • 對(duì)于變量顯式聲明提升的僅僅是聲明,賦值并未被提升;
  • 對(duì)于函數(shù)聲明由于其賦值和聲明是一體的,所以提升的是整個(gè)函數(shù)的定義;
  • 變量隱式聲明和函數(shù)表達(dá)式不會(huì)被提升。

?

思考題

1.  如果我們用函數(shù)表達(dá)式來(lái)創(chuàng)建函數(shù),而不是用函數(shù)聲明來(lái)創(chuàng)建,剛開(kāi)始的題目會(huì)如何呢?

      
        hello();


      
      
        var
      
       hello = 
      
        function
      
      
        (){
    alert(
      
      "Hello, world!"
      
        );
}
      
    

?2.  下面是一個(gè)Button類,并創(chuàng)建了一個(gè)他的實(shí)例,我們可以在瀏覽器中看到一個(gè)按鈕,但是為什么單機(jī)按鈕時(shí)alert出來(lái)的數(shù)值不是13,而是空的呢?如何能alert出我們?cè)O(shè)置的數(shù)值?

      
        function
      
      
         Button(clickFunction) {
    
      
      
        this
      
      .button = document.createElement("button"
      
        );
    
      
      
        this
      
      .button.appendChild(document.createTextNode("Test"
      
        ));
    document.body.appendChild(
      
      
        this
      
      
        .button);
    
      
      
        this
      
      .button.onclick = 
      
        function
      
      (){alert(
      
        this
      
      
        .value);}
}

      
      
        var
      
       bt = 
      
        new
      
       Button(13);    
      
        //
      
      
        單擊這個(gè)button的時(shí)候alert出空
      
    

?

?

參考資料

?

Standard ECMA-262 ECMAScript Language Specification? ?. ECMA .? June 2011

Named function expressions demystified . Juriy "kangax" Zaytsev ?.? June 17, 2009

函數(shù)式JavaScript編程指南 . ShiningRay (譯)?. 2008/01/02

Javascript的聲明


更多文章、技術(shù)交流、商務(wù)合作、聯(lián)系博主

微信掃碼或搜索:z360901061

微信掃一掃加我為好友

QQ號(hào)聯(lián)系: 360901061

您的支持是博主寫作最大的動(dòng)力,如果您喜歡我的文章,感覺(jué)我的文章對(duì)您有幫助,請(qǐng)用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點(diǎn)擊下面給點(diǎn)支持吧,站長(zhǎng)非常感激您!手機(jī)微信長(zhǎng)按不能支付解決辦法:請(qǐng)將微信支付二維碼保存到相冊(cè),切換到微信,然后點(diǎn)擊微信右上角掃一掃功能,選擇支付二維碼完成支付。

【本文對(duì)您有幫助就好】

您的支持是博主寫作最大的動(dòng)力,如果您喜歡我的文章,感覺(jué)我的文章對(duì)您有幫助,請(qǐng)用微信掃描上面二維碼支持博主2元、5元、10元、自定義金額等您想捐的金額吧,站長(zhǎng)會(huì)非常 感謝您的哦!!!

發(fā)表我的評(píng)論
最新評(píng)論 總共0條評(píng)論
主站蜘蛛池模板: 克拉玛依市| 常宁市| 仁布县| 嘉善县| 女性| 玛纳斯县| 松阳县| 安庆市| 新绛县| 织金县| 县级市| 清流县| 麟游县| 奉新县| 晋城| 汨罗市| 聂拉木县| 青浦区| 渭南市| 海安县| 林周县| 昌乐县| 清镇市| 贵定县| 望城县| 扎鲁特旗| 斗六市| 忻城县| 深州市| 邹城市| 阳春市| 嵩明县| 大姚县| 双流县| 徐州市| 敦煌市| 大荔县| 海门市| 富蕴县| 福建省| 棋牌|