參數 arguments
當一個函數被調用時候,會得到一個argments數組的參數。通過它函數可以訪問所有它被調用時傳遞給他的參數列表,包括沒有在函數定義時定義的多餘參數。
這個arguments不是真正的數組,只有一個length的屬性,並且能夠通過index遍曆。
返回 return
return語句用於返回。
如果沒有指定傳回值,則返回undefined。
如果函數用new方式來調用,且傳回值不是對象,那麼返回this(該新對象)。
異常 Exception
var add = function (a, b)
{
if(typeof a != 'number' || typeof b != 'number')
{
throw {name: 'TypeError', message: 'add needs members'};
}
}
var try_it = function ()
{
try {
add("sevem", "ee");
}
catch(e)
{
alert(e.name);
}
}();
給類型增加方法
Function.prototype.method = function (name, func)
{ if(!this.prototype[name])
{
this.prototype[name]=func;
return this;
}
};
Number.method('ins', function(){
return 2;
});
(3).ins();// value is 2.
範圍 scope
js有函數的範圍,所以定義在函數中的參數和變數在函數外部是不可見的。而且在一個函數中的任何位置定義的變數在該函數中的任何地方都可見。
在js上不用儘可能遲的申明變數,而最好的做法是在函數體的頂部聲明函數中可能用到的所有變數。
js 只有兩種環境,一種是全域環境,一種是函數環境。就是說除了函數,其他情況下的大括弧都起不了域的作用,外部環境都可以訪問大括弧內部的變數。
在函數中的this對於函數調用方式的不同分別有不同的含義。對於方法調用模式,即函數為某個對象的方法,那麼this代表對象本身。對於函數調用模式,this是全部對象,即window。對於構造器調用模式,this是prototype所指向的對象。對於Apply/call調用,this可以通過第一個參數指定。
閉包 closure
範圍的好處就是內部的函數可以訪問定義它們的外部函數的參數和變數(除了this和arguments)。
1、作為一個函數變數的一個引用,當函數返回時,處於啟用狀態。
2、一個閉包就是當一個函數返回時,一個沒有釋放資源的棧區。
3、閉包能夠保證內部變數不被直接暴露出去。被外部使用。
function a() {
var i = 0;
function b() {
alert(++i);
}
return b;
}
var c = a();
c();
如上代碼所示,c的變數實際上是指向了函數b,b中用到了變數i。當函數a內部的函數被函數外部的一個變數引用的時候,就建立了一個閉包。
所以閉包的作用就是在函數a執行完並且返回後,使得GC不會回收a所佔的資源。這個描述不夠嚴謹,但是非常直白。
為了更好的解釋閉包,引入:函數的執行環境(excution context)、使用中的物件(call object)、範圍(scope)、範圍鏈(scope chain) 這四個概念。
當定義a時,解譯器會將a的scope chain 設定為定義a的時候a所在的環境,因為a是全域函數,所以a的scope chain中只有window對象。 當執行a時,a會進入相應的excution context。 在建立執行環境的過程中,會為a添加一個scope屬性,即a的範圍,就是在定義a時scope chain 中的window對象。 然後excuation context會建立一個 call object。使用中的物件也是擁有屬性的對象。但是沒有原型也不能通過js直接存取。之後把該使用中的物件添加到a的scope chain的最頂端。這個時候a的scope chain就具備了兩個對象。然後在call object上添加arguments屬性,儲存了調用函數a時所傳遞的參數。最後把所有函數a的形參和內部參數也添加到a的使用中的物件上。
因為該函數可以訪問它被建立時所處的上下文環境。這被稱為閉包。
回調 Callbacks
把函數作為參數傳遞給函數,它將在收到響應時被調用。
模組 Module
我們可以用函數和閉包來構造模組。模組是一個提供介面卻隱藏狀態與實現的函數或對象。
級聯 Cascade
方法返回this而不是undefined.