JavaScript函數(定義、參數、返回值、閉包、匿名函數)javascript
function functionName(arg0, arg1, ... argN) { statements }
函數是一組能夠隨時隨地運行的語句。java
函數是 ECMAScript 的核心。python
函數是由這樣的方式進行聲明的:關鍵字 function、函數名、一組參數,以及置於括號中的待執行代碼。編程
普通參數:形參閉包
特殊參數:arguments。相似python裏面的sys.argv。一樣有arguments.lenght,表示參數個數。編程語言
function func1(){
if(arguments[0]=='test'){
alert('haha');
}else{
alert('gaga');
}
}
func1('test');
除非明確指定返回值(return ***),不然返回值爲undefined,同時返回空(return;)也是undefined。 函數
function sayHi(sMessage) { if (sMessage == "bye") { return sMessage; #若是參數等於‘bye’,則返回bye。不然返回undefined。 } } var a = sayHi('aaa'); alert(a);
在瞭解匿名函數前,須要瞭解一下函數對象。學習
var function_name = new function(arg1, arg2, ..., argN, function_body)
即函數的另一種定義方式,經過聲明函數的方式進行定義。其實,函數也是一種對象。ui
上面的函數咱們也能夠這樣定義:spa
var sayHi = new Function("sName", "sMessage", "alert(\"Hello \" + sName + sMessage);");
注意:前面N個參數,最後面是函數體。這種形式寫起來有些困難,但有助於理解函數只不過是一種引用類型,它們的行爲與用 Function 類明確建立的函數行爲是相同的。
函數對象的屬性:
函數對象的方法:
咱們在python裏面學習了lambda函數(匿名函數),好比定義:a=lambda x,y: x+y 調用:print a(1,3).
在JavaScript中基本上相似。
定義:
//一、 匿名函數-普通定義,無參數 var func = function(){ return ‘aaa’ } alert(func()); //二、 匿名函數直接調用-無參數 (function(){ alert("tony"); } )() //三、匿名函數直接調用-有參數 (function(arg){ console.log(arg); })('123')
做用域(基礎知識)
在學習閉包以前,咱們須要先了解JavaScript的做用域。幾乎全部的編程語言都有做用域的概念,簡單的說,做用域就是變量與函數的可訪問範圍,即做用域控制着變量與函數的可見性和生命週期。
做用域五句話原則:
function Main(){ if(1==1){ var name = 'test'; } console.log(name); } // 輸出: test。在函數內查找。
在JavaScript中每一個函數做爲一個做用域,在外部沒法訪問內部做用域中的變量。
function Main(){ var innerValue = 'test'; } Main(); console.log(innerValue);#做用域在函數內,函數外沒定義,沒法找到。 // 報錯:Uncaught ReferenceError: innerValue is not defined
因爲JavaScript中的每一個函數做爲一個做用域,若是出現函數嵌套函數,則就會出現做用域鏈。
xo = 'xxoo';//全局變量,global function Func(){ var xo = "ooxx";//函數內的局部變量,exeternal function inner(){ var xo = 'xxxx';//函數內的局部變量,local console.log(xo); } inner(); } Func();
如上述代碼則出現三個做用域組成的做用域鏈,若是出現做用域鏈後,那麼尋找變量時候就會出現順序,對於上述實例:
當執行console.log(xo)時,其尋找順序爲根據做用域鏈從內到外的優先級尋找,若是內層沒有就逐步向上找,直到沒找到拋出異常。
相似Python中的LEGB原則,首先會在local(本地)查找=>而後會到external(外部)查找=>再會查找global(全局)查找=>最後到build-in(內建)查找。進行鏈式查找!
JavaScript的做用域在被執行以前已經建立,往後再去執行時只須要按照做用域鏈去尋找便可。
因爲JavaScript是先加載完,再調用。當全部命名空間加載完成後,最後去查找,因此做用域鏈在執行前就已經建立好了。
五、JavaScript聲明提早
在JavaScript中若是不建立變量,直接去使用,則報錯:
console.log(xxoo); // 報錯:Uncaught ReferenceError: xxoo is not defined
function Foo(){ console.log(xo); var xo = 'xxoo'; } Foo(); // 輸出:undefined
上述代碼,不報錯而是輸出 undefined,其緣由是:JavaScript的函數在被執行以前,會將其中的變量所有聲明,而不賦值。因此,至關於上述實例中,函數在「預編譯」時,已經執行了var xo;因此上述代碼中輸出的是undefined。
做用域搞清楚後,理解閉包就很是簡單了。
var city = 'beijing'; function func(){ var city = "shanghai"; function inner(){ // var city = "langfang"; console.log(city); } return inner; } var ret = func(); ret(); #shanghai