《JavaScript-The Definitive Guide》讀書筆記:函數定義和函數調用


定義函數

使用function關鍵字來定義函數,分為兩種形式:

  • 聲明式函數定義;
     function add(m,n) {
        alert(m+n);
     }
    這種方式等同於構造一個Function類的實例的方式:
    var add = new Function("m", "n", "alert(m+n);");
    Function類構造方法的最后一個參數為函數體:"alert(m+n);",前面的都是函數的形參,參數必須是字符串形式的:"m","n"。
  • 函數表達式;
     1 //將一個匿名函數賦值給變量add
     2 var add = function(m, n) {
     3     alert(m + n);
     4 };
     5 add(1, 2);//3
     6 
     7 //函數表達式作為參數傳遞給其他函數
     8 var arr = [1, 3, 4, 2];
     9 arr = arr.sort(function(a, b) {
    10     return a - b;
    11 });
    12 alert(arr);//1,2,3,4
    13 
    14 //定義后立即調用
    15 alert( function(m, n) {
    16     return m + n;
    17 }(1, 2));
    18 
    19 //函數表達式也可以定義名稱(如用於遞歸)
    20 var f=function fact(x){
    21     if(x<1) {
    22         return 1;
    23     }else{
    24         return x*fact(x-1);
    25     }
    26 };

聲明式函數定義和函數表達式的一點區別

聲明式函數定義語句屬於頂級作用域范圍,函數調用語句可寫在函數聲明語句之前:

add(1, 2);//3
function add(m, n) {
    alert(m + n);
}

函數表達式定義的函數在定義之前無法調用:

//TypeError: add is not a function
add(1, 2);
var add = function(m, n) {
    alert(m + n);
};

函數的返回值

Javascript中的函數不需要聲明返回類型,使用return關鍵字返回一個值。若函數不包含return語句,或者直接使用"return;",則函數的返回值為undefined。

嵌套函數

函數可以嵌套在其他的函數里面,內層函數可以訪問外層函數的參數和變量:

function add(m, n) {

    function d(x) {
        return x * 2;
    }

    return d(m) + d(n);
}

alert(add(1, 2));//6

調用函數

函數體代碼在函數被調用時才會執行。Javascript函數有4中調用方式:

  • 普通的函數調用
  • 方法調用
  • 構造函數調用
  • 通過 call() 和 apply() 間接調用

普通的函數調用

最常用的函數調用方式,如:

alert("hello");

var result = add(1, 2);

方法調用

所謂方法就是將一個函數賦給一個對象的屬性:

 1 //定義一個函數
 2 function hello(name) {
 3     alert('hello,' + name);
 4 };
 5 var user = {};
 6 
 7 //賦值給user的sayHi屬性
 8 user.sayHi = hello;
 9 
10 //方法調用
11 user.sayHi('張三');

普通的函數調用和方法調用的一個區別:在"普通的函數調用"方式中,函數的調用上下文(this的值),為全局對象(非嚴格模式)或者undefined(嚴格模式)。而在"方法調用"方式中,this指向當前對象。利用這一特性,我們可以在方法不需要明確的返回值時,直接返回this,從而實現"方法鏈"。如jquery中常見的:

$('#btn_edit').css({color:red}).show();

嵌套函數中的this:嵌套函數中,內層函數不會繼承外層函數的this,即當內層函數作為方法調用時,內層函數的this指向當前調用對象;當內層函數作為函數調用時,this的值為全局對象(非嚴格模式)或者undefined(嚴格模式)。怎樣在內層函數中訪問外層函數的this呢?通常將this保存在一個局部變量中,通過變量來訪問:

 1 var obj = {
 2     f : function() {
 3         var self = this;
 4         console.log(this === obj);//true,this指向當前對象
 5 
 6         f1();
 7 
 8         function f1() {
 9             console.log(this === obj);//false,this為全局對象或者undefined
10             console.log(self === obj);//true,self指向外層this,即當前對象
11         }
12     }
13 };

構造函數調用

當使用new關鍵字創建一個對象時,即調用了構造函數。構造函數若沒有形參,可以省略圓括號:

var obj = new Object();
//等價於
var obj = new Object;

調用構造函數,創建了一個新對象,這個新對象會成為該構造函數的調用上下文(this的值):

function User(name) {
    this.name=name;
    console.debug(this);
}

var user = new User('張三');

call() 和 apply() 間接調用

Javascript中函數也是對象,也擁有方法。其中 call() 和 apply() 可以用來間接調用函數。call() 的第一個參數用來指定調用上下文(即this的值),后面的參數是傳入調用函數的實參。

 1 var name = 'A';
 2 var user = {
 3     name : 'B'
 4 };
 5 
 6 function showName() {
 7     alert(this.name);
 8 }
 9 
10 showName();//A,this為全局對象
11 showName.call(user);//B,this為user對象

apply() 和 call() 類似,區別在於,后面的實參需要以數組的形式傳遞(可將當前函數的arguments數組直接傳入)。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM