JavaScript是披着C族語言外衣的LISP,除了詞法上與C族語言類似之外,其餘幾乎沒有類似之處。程序員
JavaScript 函數:
函數包含一組語句,他們是JavaScript的基礎模塊單元,用於代碼複用、信息隱藏和組合調用。
函數用於指定對象的行爲。
函數對象Functions:
在JavaScript中函數就是對象。對象是「鍵值」對的集合並擁有一個鏈接到原型對象的隱藏鏈接。
對象字面量產生的對象鏈接到Object.prototype。函數對象鏈接到Function.prototype(該原型對象自己鏈接到Object.prototype)。
每一個函數在建立時都擁有兩個附加屬性:函數的上下文和實現函數行爲的代碼。
每一個函數對象在建立時也隨帶有一個prototype屬性,它的值是一個擁有constructor屬性且值即爲該函數的對象。
函數字面量Function Literal:
var add = function(a, b) {return a + b;};
經過函數字面量建立的函數對象包含一個連到外部上下文的鏈接,這被稱爲閉包。
調用Invocation:
調用一個函數將暫停當前函數的執行,傳遞控制權和參數給新函數。除了聲明時定義的形式參數,每一個函數接收兩個附加的屬性:this和arguments。
參數this在面向對象的編程中很是重要,它的值取決於調用的模式。JavaScript中一共有4中調用模式:方法調用模式、函數調用模式、構造器調用模式和apply調用模式。這些模式在如何初始化關鍵參數this上存在差別。
調用運算符():跟在任何產生一個函數值的表達式以後的一對圓括號。當實際參數(arguments)的個數與形式參數(parameters)的個數不匹配時,不會致使運行時錯誤。
方法調用模式:The Method Invocation Pattern
當一個函數被保存爲對象的一個屬性時,咱們稱它爲一個方法。當一個方法被調用時,this被綁定到該對象。若是一個調用表達式包含一個屬性存取表達式(即一個.號表達式或[subscript]下標表達式),那麼它被看成一個方法來調用。
方法可使用this去訪問對象,因此它能從對象中取值或修改該對象。this到對象的綁定發生在調用的時候。這個「超級」遲綁定(very late binding)使得函數能夠對this高度複用。經過this可取得他們所屬對象的上下文的方法稱爲公共方法。
函數調用模式:The Function Invocation Pattern
當一個函數並不是一個對象的屬性時,那麼它被看成一個函數來調用。
var sum = add(3,4);
當函數以此模式調用時,this被綁定到全局對象。
// 給myObject增長一個double方法(上面myObject對象已經有了屬性value和方法increasement)
myObject.double = function(){
var that = this;
var helper = function() {
that.value = add(that.value, that.value);
};
// The Function Invocation Pattern
helper();
}
// The Method Invocation Pattern
myObject.double();
document.writeln(myObject.getValue());
構造器調用模式:The Constructor Invocation Pattern
JavaScript是一門基於原型繼承的預言。這意味着對象能夠直接從其餘對象繼承屬性。該語言是無類別的。這偏離了當今編程的主流。當今大多數語言都是基於類的語言。儘管原型繼承有着強大的表現力,但他並不被普遍理解。JavaScript自己對其原型的本質也缺少信心,因此它提供了一套和基於類的語言相似的對象構建語法。
若是在一個函數前面帶上new來調用,那麼將建立一個隱藏鏈接到該函數的prototype成員的新對象,同時this將會被綁定到那個新對象上。
結合new前綴調用的函數被稱爲構造器函數。按照約定,他們保存在以大寫格式命名的變量裏。
Apply調用模式:The Apply Invocation Pattern
由於JavaScript是一門函數式的面向對象編程語言,因此函數能夠擁有方法。
apply方法讓咱們構建一個參數數組並用其去調用函數。它也容許咱們選擇this的值。
apply方法接收兩個參數。第一個參數將被綁定給this。第二個就是一個參數數組。
參數Arguments:
當函數被調用時,會獲得一個「免費」奉送的變量arguments數組。經過它函數能夠訪問全部它被調用時傳遞給它的參數列表,包括那些沒有被分配給函數聲明時定義的形式參數的多餘參數。這使得編寫一個無須指定參數的函數成爲可能。
arguments是一個相似數組(array-like)的對象,他並非真正的數組。有length屬性,但沒有數組的其餘方法。
返回Return:
一個函數老是會返回一個值,若是沒有指定返回值,則返回undefined。
若是函數以在前面加上new前綴的方法來調用,且返回值不是一個對象,則返回this(該新對象)。
異常Exceptions:try catch throw
給類型增長方法:
JavaScript容許給語言的基本類型增長方法(經過prototype)。
Function.prototype.method = function (name, method) {if(this.prototype[name]){this.prototype[name] = method; return this;}};
經過給Function.prototype對象增長一個method方法,咱們就沒必要鍵入prototype這個屬性名。
Number.method('integer', function () {return Math[this < 0 ? 'ceiling' : 'floor'](this);});
String.metho('trim', function () {return this.replace('/^\s+|\s+$/g','');});
經過給基本類型增長方法,咱們能夠大大提升語言的表現力。由於JavaScript是原型繼承的動態本質(在屬性訪問符調用時,一層一層檢查),新的方法馬上被賦予到全部的值(對象)上,哪怕值(對象)是在方法被建立以前就建立好了。
另外一個須要注意的是for in 語句在原型上時表現很糟糕。能夠用hasOwnProperty方法篩選出繼承而來的屬性。
遞歸Recursion:漢諾塔難題
做用域Scope:
在編程語言中,做用域控制着變量與參數的可見性和生命週期。對程序員來講這是一個重要的幫組,由於它減小了名稱衝突,而且提供了自動內存管理。
閉包Closure:
做用域的好處是內部函數能夠訪問定義在它們外部的參數和變量(除了this和arguments)。
回調Callbacks:
模塊Module:
咱們可使用函數和閉包來構造模塊。模塊是一個提供接口卻隱藏狀態與實現的函數或對象。經過使用函數去產生模塊,咱們幾乎能夠徹底摒棄全局變量的使用,從而緩解這個JavaScript的最爲糟糕的特性之一所帶來的影響。
模塊的通常形式:一個定義了私有變量和函數的函數;利用閉包建立能夠訪問私有變量和函數的特權函數。最後返回特權函數,或者把他們保存到一個能夠訪問到的地方。
級聯Cascade:
有一些方法沒有返回值。若是咱們讓這些方法返回this而不是undefined,就能夠啓動級聯(例子:jQuery的鏈式調用)。
套用Curry:
記憶Memoization:
函數能夠用對象去記住先前的結果,從而能避免無謂的運算。這種優化被稱爲記憶。 編程