亚洲免费在线-亚洲免费在线播放-亚洲免费在线观看-亚洲免费在线观看视频-亚洲免费在线看-亚洲免费在线视频

Javascript的聲明

系統 2672 0
Quiz

?

下面Javascript代碼為什么能運行?

      
        hello();


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

但對于C,這么寫會報錯:

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


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

由于hello沒有被預先聲明,代碼“hello()”被認為是隱式聲明,而隱式聲明返回類型是int,所以提示hello類型錯誤。

通過預先聲明或者將main函數放在hello函數的后面可以很容易解決這個問題。

那么對于Javascript卻能運行,這代表了什么呢?

?

被提升的聲明

Javascript引擎會先對代碼解釋,將聲明提升,然后再執行。例如為了判斷一個變量定義與否,如果我們如此寫是會出引用錯誤的:

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

但如果這樣卻不會出錯:

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

可見聲明被提升了,但只有聲明被提升了,因為someVar依然等于undefined,而不是1。

值得一提的是,這樣子寫也會報錯:

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

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

?

chrome瀏覽器的詭異現象

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

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

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

?

函數的兩種創建方式

函數申明:

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

函數表達式:

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

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

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

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

譯注:實際上FunctionDeclaration和FunctionExpression都是函數產生的語法,這和一般編程語言中函數聲明只是定義接受參數數量及類型與返回值類型不太相同?;蛘哒f,這根本不是字面意義上的函數聲明。我們可以理解對于Javascript的函數聲明(FunctionDeclaration)其實是聲明式(即需要提升的)函數產生語法,而函數表達式(FunctionExpression)則是表達式式(即執行時產生)函數產生語法。

—— WhiteSnow

主要為了區分函數的創建是否需要被提升,如果是函數聲明就需要被提升創建,但如果是表達式,那么可以在執行時再創建。這樣是很必要的,比如我們可以利用表達式動態定義函數:

      
        var
      
      
         foo;


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

再比如對于匿名函數:

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

聲明提升也沒什么意義,因為它不會在別的地方被引用。

?

如何判斷函數聲明與函數表達式

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

本文不準備深入命名函數表達式(named function expressions),具體可參見參考文獻,不過一般應當避免命名函數表達式的使用,因為大部分功能都可以用匿名函數找到替代方案,或者說實際使用中不必考慮命名函數表達式。

?

匿名函數立刻執行

我們經常希望匿名函數定義好后立刻執行,但這么寫會拋出語法錯誤:

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

正確寫法如下。

  • 聲明一個函數對象,然后執行它:
      (
      
        function
      
      
        (){
    alert(
      
      1
      
        );
})();
      
    
  • 用括號強制執行:
      (
      
        function
      
      
        (){
    alert(
      
      1
      
        );
}());
      
    
  • 使用void操作符:
      
        void
      
      
        function
      
      
        (){
    alert(
      
      1
      
        );
}();
      
    

?

總結

  • Javascript中聲明會被提升;
  • 對于變量顯式聲明提升的僅僅是聲明,賦值并未被提升;
  • 對于函數聲明由于其賦值和聲明是一體的,所以提升的是整個函數的定義;
  • 變量隱式聲明和函數表達式不會被提升。

?

思考題

1.  如果我們用函數表達式來創建函數,而不是用函數聲明來創建,剛開始的題目會如何呢?

      
        hello();


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

?2.  下面是一個Button類,并創建了一個他的實例,我們可以在瀏覽器中看到一個按鈕,但是為什么單機按鈕時alert出來的數值不是13,而是空的呢?如何能alert出我們設置的數值?

      
        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);    
      
        //
      
      
        單擊這個button的時候alert出空
      
    

?

?

參考資料

?

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

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

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

Javascript的聲明


更多文章、技術交流、商務合作、聯系博主

微信掃碼或搜索:z360901061

微信掃一掃加我為好友

QQ號聯系: 360901061

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

【本文對您有幫助就好】

您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描上面二維碼支持博主2元、5元、10元、自定義金額等您想捐的金額吧,站長會非常 感謝您的哦?。?!

發表我的評論
最新評論 總共0條評論
主站蜘蛛池模板: 国产a v高清一区二区三区 | 久久97精品久久久久久清纯 | 亚洲精品一区二区在线播放 | 2020国产精品视频免费 | 麻豆一区二区 | 成年女人免费观看视频 | 久久精品国产国产精品四凭 | 在线看片a | 国产欧美在线不卡 | julia中文字幕在线观看 | 国内在线观看 | 青青青国产 | 精品一区二区三区在线视频观看 | 97在线观免费视频观看 | 国产精品入口牛牛影视 | 国产福利视频一区 | 吃奶japanesevideo 处videossex第一次中 | 久久99青青久久99久久 | 99热这里只有精品6免费 | 国产乱肥老妇精品视频 | 视频一区免费 | 精品麻豆| 色拍自拍亚洲综合在线 | 亚洲第一在线 | 天天操天天添 | 国产精品白丝喷水在线观看 | 成人二区| 久久天天躁狠狠躁夜夜呲 | 久久依人 | 成人国产精品一区二区网站 | 亚洲国产日韩a在线亚洲 | 久久久网久久久久合久久久久 | 久久久久久久久久免免费精品 | 你懂的日韩| 亚洲美日韩 | 免费中日高清无专码有限公司 | 久久久中文字幕日本 | 青青青国产手机免费视频 | 成人精品视频一区二区在线 | 老妇综合久久香蕉蜜桃 | 日韩中文字幕一区二区不卡 |