[原]JavaScript必備知識系列-new的原理


原型對象概念

無論什么時候,只要創建一個新函數,就會根據一組特定的規則為該函數創建一個prototype屬性,這個屬性指向函數的原型對象。在默認情況下,所有原型對象都會自動獲得一個constructor(構造函數)屬性,這個屬性包含一個指向 prototype 屬性所在函數的指針。而通過這個構造函數,可以繼續為原型對象添加其他屬性和方法。創建了自定義的構造函數后,其原型對象默認只會取得 constructor 屬性;至於其他方法,則都從 Object 繼承而來。當調用構造函數創建一個新實例后,該實例的內部將包含一個指針(內部屬性),指向構造函數的原型對象。ECMA-262第5版管這個指針叫 [[Prototype]] 。腳本中沒有標准的方式訪問 [[Prototype]],但Firefox、Safari和Chrome在每個對象上都支持一個屬性__proto__;而在其他實現中,這個屬性對腳本是完全不可見的。不過,要明確的真正重要的一點就是,這個連接存在於示例和構造函數的原型對象之間,而不是存在於實例和構造函數之間。

這段話基本概述了構造函數、原型、示例之間的關系,下圖表示更清晰

通過new創建對象經歷4個步驟

1、創建一個新對象;[var o = new Object();]

2、將構造函數的作用域賦給新對象(因此this指向了這個新對象);[Person.apply(o)]  [Person原來的this指向的是window]

3、執行構造函數中的代碼(為這個新對象添加屬性);

4、返回新對象。

通過代碼還原new的步驟:

function Person(name, age) {

    this.name = name;

    this.age = age;

    this.sayName = function() {

        alert(this.name);

    }

}

function createPerson(P) {

    var o = new Object();

    var args = Array.prototype.slice.call(arguments, 1);

    o.__proto__ = P.prototype;

    P.prototype.constructor = P;

    P.apply(o, args);

    return o;

}

new()過程中的原型鏈維護

new總是因為建立原型繼承樹而存在的,如果沒有new過程參與,則當

obj = new MyObjecEx()時,我們無法通過instanceof運算:obj instanceof MyObject 來了解obj在繼承樹上的關系。但是事實上這一過程並不需要MyObject的參與。因為instanceof只檢查prototype鏈,並不檢查函數本身。

new新對象的創建,就是不斷地為this賦值而已,只不過new會為產生的對象維護<obj>.constructor屬性。


免責聲明!

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



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