前端學習筆記——Js函數function基礎理解

學習內容來自:《JavaScript高級程序設計(第三版)》segmentfault

正文:咱們知道,在js中,函數其實是一個對象,每一個函數都是Function類型的實例,而且都與其餘引用類型同樣具備屬性和方法。所以,函數名其實是指向函數對象的指針,不與某個函數綁定。在常見的兩種定義方式(見下文)以外,還有一種定義的方式能更直觀的體現出這個概念:閉包

var sum = new Function("num1", "num2", "return num1 + num2"); //不推薦

  Function的構造函數能夠接收任意數量的參數,但最後一個參數始終被看作函數體。這種方式有個缺點是,會致使解析兩次代碼,第一次是基礎的ES代碼解析,第二次是解析傳入構造函數中的字符串,這樣會致使性能的降低,在此寫出是幫助理解js中函數實際上是對象這個概念。框架

 (一)js函數沒有重載的概念函數

  說到重載的概念,咱們來類比Java中的重載是怎麼實現的:在Java中,方法是經過方法簽名來惟一標識一個方法。方法簽名包括:方法名、參數數量、參數順序和參數類型這幾個要素。所以兩個方法的方法名相同,而其餘簽名要素不一樣,編譯器就會認爲是兩個不一樣方法,從而能夠存在同名的不一樣方法,以實現重載的概念。(引用:怎麼深刻理解js中爲何沒有重載呢--segmentfault  中manxisuo的回答)。性能

  而上面咱們說過,js中的函數名其實是指向函數對象的指針,所以函數名能夠說是一個函數的惟一標識,跟參數列表並無關係,所以並不會出現同名的兩個函數(由於一個指針同時只能指向一個對象)從而不存在重載的概念。 舉個栗子:學習

function sum(num1, num2){
    return num1 + num2;
}

function sum(num1, num2, num3){
    return num1 + num2 + num3;
}

  上面這種能夠換一種寫法,會更直觀一些:spa

var sum = function(num1, num2){
    return num1 + num2;
}

sum = function(num1, num2, num3){
    return num1 + num2 + num3;
}

  這樣就很明顯能夠看出,上面一行將sum指向function(num1,num2),而接下來又將sum指向function(num1, num2, num3),從而形成第二次的指向覆蓋了第一次的,所以更明顯的看出js中並無重載的概念。設計

 

(二)函數聲明和函數表達式的區別指針

  咱們知道,經常使用的定義函數方法有兩個:函數聲明和函數表達式。code

  函數聲明,能夠說是最多見的定義方法,以下例:

function sum(num1, num2){
    return num1 + num2;
}

  函數表達式,這種定義方式在閉包及一些框架中使用較多,例如angular中常見的$scope.doSomething = function(){...}:

sum = function(num1, num2){
    return num1 + num2;
};

  上述兩種定義方法幾乎是相同的,但有一點小區別,請看下面這個例子:

//函數聲明
alert(sum(100, 100));
function sum(num1, num2){
    return num1 + num2;
}
//函數表達式
alert(sum(100, 100));
var sum = function(num1, num2){
    return num1 + num2;
};

  這兩段代碼看起來差異不大,只是函數定義的方式不一樣而已。但事實是,第一段能夠正常運行而第二段則會報錯。這是由於,在代碼開始執行以前,解析器就已經經過一個名爲函數聲明提高的過程,讀取並將函數聲明添加到執行環境中。簡單來講,解析器會先將函數聲明放在源代碼樹的頂部。而下面那段代碼,函數位於一個初始化語句中(並不會將其提高到頂部),簡單來講,在執行到這個賦值語句以前,sum並未指向任何一個函數,所以在以前調用函數則會報錯。

  --待續--

相關文章
相關標籤/搜索