函數聲明與函數表達式

函數是JavaScript非常重要的一部分,它被稱爲第一等公民,可以看出它的地位是何等尊貴何等重要。根據我一貫的作風,會深入原理性的東西,那這篇文章主要來挖掘函數聲明與函數表達式相關知識。

在JavaScript中定義一個函數有四種方式

  • 函數聲明
  • 函數表達式
  • ES6裏箭頭函數
  • new Function()

函數聲明

語法

function 函數名(參數){
    要執行的代碼
}

調用

  1. 函數名(參數)
  2. 函數名.call(函數名,參數)
  3. 函數名.apply(函數名,[參數])
  4. new 函數名(參數)
  5. 定時器
  6. 把函數聲明變成函數表達式再調用
  7. ES6裏的模版字符串
function fn(text){
    console.log(text);
}

fn('直接調用');

fn.call(fn,'用call調用');

fn.apply(fn,['用apply調用']);

new fn('用new調用');

setTimeout(fn('用定時器調用'));

(function fn(text){
    console.log(text);
})('轉成函數表達式後調用');

fn`用模版字符串調用`;   //ES6里語法

函數表達式

語法

var/let/const 變量=function(參數){
    要執行的代碼
}

調用

  1. 函數名(參數)
  2. 函數名.call(函數名,參數)
  3. 函數名.apply(函數名,[參數])
  4. new 函數名(參數)
  5. 直接在後面加上一對小括號
  6. 定時器
  7. ES6裏的模版字符串
  8. 以被賦值的形式出現(根據具體形式調用)
const fn=function(text){
    console.log(text);
};

fn('直接調用');

fn.call(fn,'用call調用');

fn.apply(fn,['用apply調用']);

new fn('用new調用');

const fn2=function(text){
    console.log(text);
}('直接在後面加小括號調用');

setTimeout(fn('用定時器調用'));

fn`用模版字符串調用`;

document.onclick=function(){
    console.log('以被賦值的形式出現也是一個函數表達式');
};

函數聲明與函數表達式的區別

  1. 函數聲明必須帶有標識符(函數名稱),函數表達式則可以省略
    • 表達式裏的名字不能在函數外面用,只能在函數內部用
    • 函數有一個name屬性,指向緊跟在function關鍵字之後的那個函數名。如果函數表達式沒有名字,那name屬性指向變量名
  2. 函數聲明會被預解析,函數表達式不會
//1、名字
//函數聲明必需帶名字
function fn(){};
//function(){};     //報錯,沒有名字

//函數表達式可以沒有名字
let fn1=function(){};
(function(){});
!function(){};

//表達式名字的作用
let fn2=function newFn(){
    console.log(newFn); //可以在這裏面用。有一個作用就是在這裏用遞歸
};
fn2();
//newFn();  //報錯,不能在外面用

//name屬性
console.log(
    fn.name,    //fn
    fn1.name,   //fn1   表達式沒有名字,name屬性指向表達式變量名
    fn2.name    //newFn
);      

//2、預解析
fn3();
function fn3(){
    console.log('fn3');
}

//fn4();    //報錯,不會被預解析
let fn4=function(){
    console.log('fn4');
}

自執行函數

自執行函數也叫立即調用的函數表達式(IIFE)。它的作用爲我們不用主動地去調用函數,它會自己調用,對於做模塊化、處理組件是非常有用的。
首先來看一個問題,調用函數最簡單的方法就是加一對小括號,那我在函數聲明的末尾加一對括號後,這個函數能否調用呢?

function fn(){
    console.log(1);
}();    //報錯

const fn1=function(){
    console.log('表達式執行');
}();    //執行函數

函數聲明不能直接調用的原因

  1. 小括號裏只能放表達式,不能放語句
  2. function關鍵字即可以當作語句,也可以當作表達式。但js規定function關鍵字出現在行首,一律解釋成語句

解決方法:不要讓function出現在行首

  1. 用括號把function主體括起來,轉成表達式。後面加括號運行
  2. 藉助運算符(new + - ! ~ typeof , && ||...)
    因爲運算符會把表達式執行,執行後得出結果了才能運算
//小括號裏只能放表達式
(
    if(true){
        console.log(1);
    }
)//報錯,括號裏不能放語句

(1);
(1+2);
([1]);
({});

function fn(){
    console.log('函數聲明執行');
}(1);   //符合語法,但是函數不會執行

//想要執行就必需把函數聲明轉成表達式,而小括號裏只能放表達式,利用這個特徵把函數放在一對括號裏,再加一對括號就能執行
(function fn(){
    console.log('函數聲明執行');
})();
//或者這樣也可以執行
(function fn(){
    console.log('函數聲明執行');
}());

只要把函數聲明轉成表達式,再加上括號就可以聲明。那就有很多稀奇古怪的方式來執行函數

0+function(text){
    console.log(text);
}('與數字相加變成表達式');

true&&function(text){
    console.log(text);
}('利用邏輯運算符變成表達式');

false||function(text){
    console.log(text);
}('利用邏輯運算符變成表達式');

0,function(text){
    console.log(text);
}('利用逗號運算符變成表達式');

//二進制位取反運算符
~function(text){
    console.log(text);
}('前面加上+-!~變成表達式');

new function(text){
    console.log(text);
}('利用new運算符變成表達式');

typeof function(text){
    console.log(text);
}('利用typeof運算符變成表達式');
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章