《javascript語言精粹》讀書筆記 —— 第4章 :函數

一、對象是"key-value"對的集合,並擁有一個連到原型對象的隱形連接。 javascript

二、javascript中函數就是對象。 java

三、函數對象與普通對象的區別: 數組

   a、 對象字面量產生的對象(非函數對象)鏈接到Object.prototype,函數對象則鏈接到Function.prototype(該原型自己鏈接到Object.prototype). app

   b、函數對象在建立時會附加兩個隱藏屬性:函數的上下文和實現函數行爲的代碼。 函數

   c、函數能夠被調用 優化

四、函數對象經過函數字面量來建立: this

var add = function (a, b) {
    return a + b;
}
函數字面量包括四個部分:(1)保留字 function (2)函數名 <可選> (3)參數 (4)函數體


五、調用模式 spa

    (1)方法調用模式: prototype

           當一個函數被保存爲一個對象的屬性時,咱們稱它爲一個方法。此時方法中的this 指向的是方法所屬的 設計

           對象。this到對象的綁定是發生在調用的時候。

     (2)函數調用模式:

           當一個函數非一個對象屬性時,它就是當作一個函數來調用的。此時函數中的this被綁定到全局對象。

           這是語言設計上的錯誤。若是方法(注意是方法)裏面定義了一個函數,那麼函數中的this指向的是全局

           對象,而方法中的this指向的是方法所屬的對象。

          解決方案以下:

myObject.double = function (){
    var that = this //解決方法
    
    //這是一個內部函數
    var helper = function(){
       //此時用that來指向myObject對象
       that.value = add(that.value, that.value);
    };
    helper();

}
      (3)、構造器調用模式:


    javascript是一門基於原型繼承的語言。這意味着對象能夠直接從其餘對象繼承屬性。該語言是無類型的

  若是在一個函數前面帶上new 來調用,那麼背地裏將會建立一個鏈接到該函數的prototype成員的新對象,同時

  函數體中的this指向的就是被新建立的對象。

var Quo = function (message){
    //此時的this還未綁定
    this.status = message;
}

Quo.prototype.get_status = function(){
    //此時this未綁定
    return this.status;
}

//構造一個對象,此時Quo函數體中的this指向的是myQuo對象
var myQuo =  new Quo("confused");

//打印confused
document.writeln(myQuo.get_status());

      (4)apply 調用模式

      由於函數也是對象,因此函數也能夠擁有方法。(apply是函數對象被建立時附加的一個方法)apply接收兩個參數,第一個是要綁定給this的值(其實就是函數調用時的上下文),第二個是一個參數數組。

var array = [3, 4];
//此時至關於直接調用 add(3,4);
var sum = add.apply(null, array); //sum爲7

var statusObject = {
    status : 'A-OK';
}
//this只有在調用時才被綁定,而apply的第一個參數就是用來綁定this的
 var status = Quo.prototype.get_status.apply(statusObject)//status 爲‘A-OK'


六、參數

函數被調用時,會獲得一個」免費「配送的參數,那就是arguments數組。函數經過此參數能夠訪問全部它被調用時傳給它的參數列表,包括那些沒有分配給函數聲明定義的形式參數的多餘參數。這使得編寫一個無需指定參數個數的函數成爲可能。

var sum = function(){
    
    var i, sum = 0;
    
    for (i = 0; i < agruments.length; i +=1){
        sum += arguments[i];
    }
    
    return sum;

}

document.writeln(sum(1,2,3,4); //返回 10
注意:因爲語言設計錯誤,arguments 並非一個真正的數組。它只是一個」相似「數組的對象。arguments擁有一個length屬性,但它沒有數組的其餘對象。

七、返回

一個函數總會有一個返回值。若是沒有指定返回值,則返回一個undefined。

若是函數調用時在前面加上了 new 前綴 ,且返回值不是一個對象,則返回this(該新對象)

var Quo = function (message){
      //此時的this還未綁定
      this.status = message;
      var ob = {};
      //返回一個對象
      return ob;
}

//此時myObj 就是 {} 空對象
var myObj = new Quo("ss")
 
八、異常

javascript中的try 語句只會有一個捕獲全部異常的catch代碼塊。若是你的處理手段取決於異常的類型,那麼異常處理器必須檢查異常對象的name屬性來肯定異常的類型。

var add = function(a, b){
    if (typeof a !== 'number' || typeof b !== 'number'){
          throw {
               name: 'Type error',
               message: 'add needs numbers'
          }
    }
    return a + b;

}


var try_it = function(){
  try {
      add("seven");
  }
  catch(e){
      document.writeln(e.name +':'+ e.message);
  }

}

九、擴充類型的功能

javascript 容許給語言的基本類型擴充功能。咱們能夠經過給Function.prototype增長方法來使得該方法對全部函數都有用。

例如:增長一個method方法,咱們下次給對象增長方法時就沒必要鍵入prototype這幾個字符了

Function.prototype.method = function(name, fun){
//不存在時才添加
 if(!this.prototype[name]){ 
   this.prototype [name] = fun;
 }
 return this;
}

//別忘了 Number 也是函數
Number.method('integer',function(){
    return Math[this < 0 ? 'cell' : 'floor'](this);
}

十、遞歸

      遞歸不用說了,說明一點,javascript自己不支持尾遞歸優化。


待續。。。

相關文章
相關標籤/搜索