JavaScript快速入門-ECMAScript函數

JavaScript函數(定義、參數、返回值、閉包、匿名函數)javascript

 

1、函數定義

function functionName(arg0, arg1, ... argN) {
  statements
}

函數是一組能夠隨時隨地運行的語句。java

函數是 ECMAScript 的核心。python

函數是由這樣的方式進行聲明的:關鍵字 function、函數名、一組參數,以及置於括號中的待執行代碼。編程

  

2、參數

普通參數:形參閉包

特殊參數:arguments。相似python裏面的sys.argv。一樣有arguments.lenght,表示參數個數。編程語言

    function func1(){
        if(arguments[0]=='test'){
            alert('haha');

        }else{
            alert('gaga');
        }
    }
    func1('test');

 

3、返回值

除非明確指定返回值(return ***),不然返回值爲undefined,同時返回空(return;)也是undefined。 函數

  function sayHi(sMessage) {
      if (sMessage == "bye") {
        return sMessage;  #若是參數等於‘bye’,則返回bye。不然返回undefined。
      }
    }
var a = sayHi('aaa');
alert(a);

  

4、函數對象

在瞭解匿名函數前,須要瞭解一下函數對象。學習

var function_name = new function(arg1, arg2, ..., argN, function_body)

  

即函數的另一種定義方式,經過聲明函數的方式進行定義。其實,函數也是一種對象。ui

上面的函數咱們也能夠這樣定義:spa

var sayHi = new Function("sName", "sMessage", "alert(\"Hello \" + sName + sMessage);");

  注意:前面N個參數,最後面是函數體。這種形式寫起來有些困難,但有助於理解函數只不過是一種引用類型,它們的行爲與用 Function 類明確建立的函數行爲是相同的。

 

函數對象的屬性:

  • length

函數對象的方法:

  •  valueOf() 方法
  • toString() 方法

5、匿名函數

咱們在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')

  

6、做用域

做用域(基礎知識)

 在學習閉包以前,咱們須要先了解JavaScript的做用域。幾乎全部的編程語言都有做用域的概念,簡單的說,做用域就是變量與函數的可訪問範圍,即做用域控制着變量與函數的可見性和生命週期。

做用域五句話原則:

一、JavaScript中無塊級做用域

function Main(){
    if(1==1){
        var name = 'test';
    }
    console.log(name);
}
// 輸出: test。在函數內查找。

  

二、JavaScript採用函數做用域

在JavaScript中每一個函數做爲一個做用域,在外部沒法訪問內部做用域中的變量。

function Main(){
    var innerValue = 'test';
}
 
Main();
 
console.log(innerValue);#做用域在函數內,函數外沒定義,沒法找到。
 
// 報錯:Uncaught ReferenceError: innerValue is not defined

  

三、JavaScript的做用域鏈

因爲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聲明提早

在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。

7、閉包

做用域搞清楚後,理解閉包就很是簡單了。

var city = 'beijing';

function func(){
    var city = "shanghai";
    function inner(){
        // var city = "langfang";
        console.log(city);
    }
    return inner;
}
var ret = func();
ret(); #shanghai
相關文章
相關標籤/搜索