當代碼new Animal("cat")
執行時:html
var obj=Object.create(Animal.prototype);
前端
傳入cat參數,構造函數Animal執行。同時構造函數內部的this被指定爲obj。函數
若是構造函數返回了一個「對象」,那麼這個對象就是new出來的結果。若是構造函數沒有返回對象(即返回一個非對象值,例如數值,或者無返回值
),那麼new出來的結果爲obj對象。通常狀況下構造函數不返回值,除非你想要覆蓋正常建立的對象(即obj)。this
例如:spa
function A(name){ this.name=name; return 3; } var new1=new A("aa"); new1;//A {name: "aa"} function B(name){ this.name=name; return {}; } var new2=new B("aa"); new2;//new2爲一個空對象。
JS權威指南中有一句很精闢的描述: 「JavaScript中的函數運行在它們被定義的做用域裏
,而不是它們被執行的做用域裏。」簡單來講,就是函數被調用時,它是運行在當時定義該函數時的環境中的。prototype
當定義函數a的時候,js解釋器會將函數a的做用域鏈(scope chain)設置爲定義a時所在的「環境」
,併爲a添加scope屬性,a.scope=a的做用域鏈。若是a定義在全局環境,那麼scope chain中只有window對象。code
當函數被調用時,會建立一個活動對象(call object)(也就是一個對象), 而後把全部函數a的局部變量和函數定義添加爲該活動對象的屬性
, 並將該活動對象添加到a的做用域鏈的最頂端,此時a的做用域鏈包含2個對象:a的活動對象和window對象。htm
爲何調用func1(10)和func2(10)時,引用到了兩個不一樣的i?對象
function outerFn(i, j) { var x = i + j; return function innerFn(x) { return i + x; } } var func1 = outerFn(5, 6); var func2 = outerFn(10, 20); alert(func1(10)); //返回15 alert(func2(10)); //返回20
調用outerFn (5, 6)的時候定義了一個新的函數對象innerFn,而後該函數對象成爲了outerFn函數的活動對象的一個屬性。這時innerFn的做用域鏈是由outerFn的活動對象和全局對象組成的.。這個做用域鏈存儲在了innerFn函數的內部屬性[[scope]]中,而後返回了該函數,變量func1就指向了這個innerFn函數。blog
在func1被調用時,它自身的活動對象被建立,而後添加到了[[scope]]中存儲着的做用域鏈的最前方。這時的做用域鏈纔是func1函數執行時用到的做用域鏈。從這個做用域鏈中,能夠看到變量‘i’的值實際上就是在執行outerFn(5,6)時產生的活動對象的屬性i的值。下圖顯示了整個流程。
下圖是func2執行時的狀況。由於在定義func1和func2時,函數outerFn中產生過兩個不一樣的活動對象,因此才致使調用func1(10)和func2(10)時,引用到了兩個不一樣的i。
一個活動對象在函數執行的時候建立,同時被添加到該函數的做用域鏈的最前端。當函數執行完畢時,活動對象會被從該做用域鏈上刪除。
可是該活動對象是否會被垃圾回收器銷燬,還要看其餘地方是否還有使用到該活動對象。