首頁 web前端 js教程 淺析函數宣告和函數表達式-函數宣告的宣告提前_基礎知識

淺析函數宣告和函數表達式-函數宣告的宣告提前_基礎知識

May 16, 2016 pm 03:02 PM
函數聲明

前兩天班級聚會,除了吃喝玩樂就是睡覺扯淡,甚是喜悅,真是獨樂樂不如眾樂樂啊。

PS:畢業的或即將畢業的有時間能聚就聚吧,畢了業以後屬於自己的時間能聚到一塊兒可就少太多了。

現在有點時間來看點東西總結些東西了,又因為前段時間片片斷斷地看了看JavaScript的函數部分,所以抽時間總結下函數的相關部分,當然,裡面有些部分都是自己的理解,如果有理解的不對的地方還請小夥伴們不吝指出。

這一節我結合自己的理解和小夥伴們聊一下函數宣告的宣告提前。

註:有的地方也叫函數宣告提升。翻譯的不一樣,意思一樣,大家懂就好。理解萬歲!

在聊函數宣告的宣告提前之前,有必要介紹下函數定義的幾種方法,大部分小夥伴們應該都不陌生。了解的或是不想了解的就痛快地一滾輪滾下去吧,不熟悉的或者想再熟悉一下的就放慢腳步起步走。

定義函數的方法

定義函數的方法主要有三種:

1.函數宣告(Function Declaration)
2.函數表達式Function Expression)
3.new Function建構子
其中,經常使用的是函數聲明和函數表達式的函數定義方法,這兩種方法有著很微妙的區別和聯繫,而且這兩種方法的使用也容易混淆,所以這篇文章主要總結下這兩種函數定義方法的相關知識點,當然本文的主題依然是關於函數提前的。

函數宣告的典型格式:

function functionName(arg1, arg2, ...){
  <!-- function body -->
}
登入後複製

函數表達式

•函數表達式的典型格式:

var variable=function(arg1, arg2, ...){
      <!-- function body -->
}
登入後複製

包含名稱(括弧,函數名)的函數表達式:

var variable=function functionName(arg1, arg2, ...){
    <!-- function body -->
}
登入後複製

像上面的帶有名稱的函數表達式可以用來遞歸:

var variable=function functionName(x){
    if(x<=1)
      return 1;
    else
      return x*functionName(x);
}
登入後複製

聲明提前

var聲明提前

小夥伴們應該都聽說過宣告提前的說法,我想在此再次重申一遍,因為宣告提前是函數宣告和函數表達式的一個重要區別,對於我們進一步理解這兩種函數定義方法有著重要的意義。

但是再說函數宣告提前之前呢,有必要說一下var宣告提前。

先給出var聲明提前的結論:

變數在宣告它們的腳本或函數中都是有定義的,變數宣告語句會被提前到腳本或函數的頂端。但是,變數初始化的操作還是在原來var語句的位置執行,在宣告語句之前變數的值是undefined。

上面的結論中可以總結出三個簡單的點:

1.變數宣告會提前到函數的頂端;
2.只是宣告被提前,初始化不提前,初始化還在原來初始化的位置進行初始化;
3.在宣告之前變數的值是undefined。

還是來例子實在:

var handsome='handsome';
function handsomeToUgly(){
  alert(handsome);
  var handsome='ugly';
  alert(handsome);
}
handsomeToUgly();
登入後複製

正確的輸出結果是:
先輸出undefined,然後輸出ugly。

錯誤的輸出結果是:
先輸出handsome,然後輸出ugly。

這裡正是變數宣告提前起到的作用。該handsome局部變量在整個函數體內都是有定義的,在函數體內的handsome變量壓住了,哦不對,是覆蓋住了同名的handsome全局變量,因為變量聲明提前,即var handsome被提前至函數的頂部,就是這個樣子:

var handsome='handsome';
function handsomeToUgly(){
  var handsome;
  alert(handsome);
  var handsome='ugly';
  alert(handsome);
}
handsomeToUgly();
登入後複製

所以說在alert(handsome)之前,已經有了var handsome聲明,由上面提到的

在宣告之前變數的值是undefined
所以第一個輸出undefined。

又因為上面提到的:

只是宣告被提前,初始化不提前,初始化還在原來初始化的位置進行初始化
所以第二個輸出ugly。

函數宣告提前
接下倆我們結合var宣告提前開始聊函數宣告的宣告提前。

函數宣告的宣告提前小夥伴應該很熟悉,舉個再熟悉不過的例子。

sayTruth();<!-- 函数声明 -->
function sayTruth(){
  alert('myvin is handsome.');
}

sayTruth();<!-- 函数表达式 -->
var sayTruth=function(){
  alert('myvin is handsome.');
}
登入後複製

小伙伴们都知道,对于函数声明的函数定义方法,即上面的第一种函数调用方法是正确的,可以输出myvin is handsome.的真理,因为函数调用语句可以放在函数声明之后。而对于函数表达式的函数定义方法,即上面的第二种函数调用的方法是不能输出myvin is handsome.的正确结果的。

结合上面的myvin is handsome.例子,函数声明提前的结论似乎很好理解,不就是在使用函数声明的函数定义方法的时候,函数调用可以放在任意位置嘛。对啊,你说的很对啊,小伙伴,我都不知道怎么反驳你了。那就容我再扯几句。

从小伙伴所说的

不就是在使用函数声明的函数定义方法的时候,函数调用可以放在任意位置嘛
可以引出一点:

函数声明提前的时候,函数声明和函数体均提前了。

而且:

函数声明是在预执行期执行的,就是说函数声明是在浏览器准备执行代码的时候执行的。因为函数声明在预执行期被执行,所以到了执行期,函数声明就不再执行(人家都执行过了自然就不再执行了)。

上面是一点。

函数表达式为什么不能声明提前
我们再说一点:为什么函数表达式不能像函数声明那样进行函数声明提前呢?

辛亏我知道一点儿,否则真不知道我该怎么回答呢?

咳咳,按照我的理解给小伙伴们解释一下下:

我们上面说了var的声明提前,注意我上面提过的:

只是声明被提前,初始化不提前,初始化还在原来初始化的位置进行初始化

Ok,我们把函数表达式摆在这看看:

var variable=function(arg1, arg2, ...){
          <!-- function body -->
}
登入後複製

函数表达式就是把函数定义的方式写成表达式的方式(貌似是白说,但是这对于解释和理解为毛函数表达式不能函数声明提前具有良好的疗效),就是把一个函数对象赋值给一个变量,所以我们把函数表达式写成这个样子:

var varible=5看到这,也许小伙伴们会明白了,一个是把一个值赋值给一个变量,一个是把函数对象赋值给一个变量,所以对于函数表达式,变量赋值是不会提前的,即function(arg1, arg2, ...){}是不会提前的,所以函数定义并没有被执行,所以函数表达式不能像函数声明那样进行函数声明提前。

函数声明提前的实例分析

还是那句话,还是例子来的实在:

sayTruth();
if(1){
  function sayTruth(){alert('myvin is handsome')};
}
else{
  function sayTruth(){alert('myvin is ugly')};
}
登入後複製

在浏览器不抛出错误的情况下(请自行测试相应的浏览器是否有抛出错误的情况,为啥我不测试?我能说我懒么。。。),浏览器的输出结果是输出myvin is ugly(我不愿承认,但是事实就是这样啊啊啊啊,难道道出了人丑就该多读书??????)。

为什么呢?当然是声明提前了。因为函数声明提前,所以函数声明会在代码执行前进行解析,执行顺序是这样的,先解析function sayTruth(){alert('myvin is handsome')},在解析function sayTruth(){alert('myvin is ugly')},覆盖了前面的函数声明,当我们调用sayTruth()函数的时候,也就是到了代码执行期间,声明会被忽略,所以自然会输出myvin is ugly(好残酷的现实。。。)。忘了的可以看上面说过的:

函数声明是在预执行期执行的,就是说函数声明是在浏览器准备执行代码的时候执行的。因为函数声明在预执行期被执行,所以到了执行期,函数声明就不再执行了(人家都执行过了自然就不再执行了)。

小了个结

关于函数声明的函数提前(提升)就聊到这里先,希望我的理解和扯淡能够对有需要的小伙伴有所帮助。

当然,实践出真知。对事物的了解、认知和运用还是在于多看多用多总结,记得有句名言,是讲声明和实践的:“动起来,为新的声明喝彩。”。

以上这篇浅析函数声明和函数表达式——函数声明的声明提前就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持脚本之家。

本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn

熱AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover

AI Clothes Remover

用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool

Undress AI Tool

免費脫衣圖片

Clothoff.io

Clothoff.io

AI脫衣器

Video Face Swap

Video Face Swap

使用我們完全免費的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱工具

記事本++7.3.1

記事本++7.3.1

好用且免費的程式碼編輯器

SublimeText3漢化版

SublimeText3漢化版

中文版,非常好用

禪工作室 13.0.1

禪工作室 13.0.1

強大的PHP整合開發環境

Dreamweaver CS6

Dreamweaver CS6

視覺化網頁開發工具

SublimeText3 Mac版

SublimeText3 Mac版

神級程式碼編輯軟體(SublimeText3)

熱門話題

Java教學
1664
14
CakePHP 教程
1422
52
Laravel 教程
1316
25
PHP教程
1268
29
C# 教程
1240
24
C++ 函數宣告中的預設參數:全面解析其宣告和用法 C++ 函數宣告中的預設參數:全面解析其宣告和用法 May 02, 2024 pm 03:09 PM

C++中的預設參數提供函數參數指定預設值的功能,從而增強程式碼可讀性、簡潔性和靈活性。宣告預設參數:在函數宣告中將參數後面加上"="符號,後面接著預設值。用法:函數呼叫時,若未提供可選參數,則會使用預設值。實戰案例:計算兩個數之和的函數,一個參數必填,另一個可填且有預設值0。優點:增強可讀性、增加彈性、減少樣板程式碼。注意事項:只能在聲明中指定,必須位於末尾,類型必須相容。

C++ 函數的宣告和定義的順序有什麼影響? C++ 函數的宣告和定義的順序有什麼影響? Apr 19, 2024 pm 01:42 PM

在C++中,函數宣告和定義的順序會影響編譯和連結過程。最常見的是聲明在前,定義在後;也可使用「forwarddeclaration」將定義放在聲明前;如果兩者同時存在,編譯器將忽略聲明,僅使用定義。

C++ 函式宣告和定義有什麼差別? C++ 函式宣告和定義有什麼差別? Apr 18, 2024 pm 04:03 PM

函數聲明告知編譯器函數的存在,不包含實現,用於型別檢查。函數定義提供實際實現,包含函數體。區分的關鍵特徵包括:目的、位置、作用。理解差異對於編寫有效且可維護的C++程式碼至關重要。

C++ 函式的宣告與定義 C++ 函式的宣告與定義 Apr 11, 2024 pm 01:27 PM

函數宣告和定義在C++中是必要的,函數宣告指定函數的傳回類型、名稱和參數,而函數定義包含函數體和實作。首先聲明函數,然後在程式中使用它並傳遞所需的參數。使用return語句從函數傳回一個值。

C++編譯錯誤:函式呼叫與函式宣告不符,該怎麼解決? C++編譯錯誤:函式呼叫與函式宣告不符,該怎麼解決? Aug 22, 2023 pm 12:39 PM

C++編譯錯誤:函式呼叫與函式宣告不符,該怎麼解決?在開發C++程式時,難免會遇到一些編譯錯誤,其中一個常見的錯誤是函式呼叫與函式宣告不符的錯誤。這種錯誤廣泛存在於C++程式設計師中,由於不注意函數宣告的正確性,導致編譯問題,最終浪費時間和精力修復問題,影響開發效率。避免這種錯誤的方法需要遵循一些規範和標準實踐,以下讓我們來了解一下。什麼是函數呼叫與函數宣告不

C++ 函數宣告中的[[nodiscard]]:揭開忽略返回值後果的神秘面紗 C++ 函數宣告中的[[nodiscard]]:揭開忽略返回值後果的神秘面紗 May 01, 2024 pm 06:18 PM

[[nodiscard]]屬性指示函數的回傳值不得忽略,否則將導致編譯器警告或錯誤,以防止以下後果:未初始化異常、記憶體洩漏和錯誤的計算結果。

C++ 函式宣告的詳細語法:從語法解析到規範用法解析 C++ 函式宣告的詳細語法:從語法解析到規範用法解析 Apr 30, 2024 pm 02:54 PM

C++函式宣告語法為:returnTypefunctionName(parameterType1parameterName1,...,parameterTypeNparameterNameN);,其中returnType為傳回型別,functionName為函式名,parameterType為參數類型,parameterName為參數名,必須以分號結尾。

C++ 函數宣告的逐步指南:涵蓋每個步驟的詳細說明 C++ 函數宣告的逐步指南:涵蓋每個步驟的詳細說明 May 02, 2024 pm 04:33 PM

函數聲明告訴編譯器函數的存在,無需提供函數體。步驟如下:指定函數傳回類型(void如果無返回值)定義函數名稱聲明函數參數(可選,包括資料類型和識別碼)加分號

See all articles