JS中的原型對象(一)

理解原型對象

每創建一個函數,就會同時創建它的 Prototype 對象,即原型對象。每個函數都有一個 prototype 屬性,這個屬性指向函數的原型對象。在默認情況下,所有原型對象都會自動獲取一個 constructor(構造函數) 屬性,這個屬性是一個指向 prototype 屬性所在函數的指針。例如:

function Person(){
    }

Person.prototype.constructor 指向 Person 。通過這個構造函數,我們還可以爲原型對象添加其他屬性和方法,如下所示:

function Person( ){
}
Person.prototype.name = "Nicholas";
}
var person1=new Person( );
person1.sayName( ); //"Nicholas"

var person2 = new Person( );
person2.sayName( ); //"Nicholas"

雖然無法直接訪問Prototype,但可以通過isPrototypeOf( )方法確定對象之間是否存在這種關係。例如:

alert(Person.prototype.isPrototypeOf(person1)); //true
alert(Person.prototype.isPrototypeOf(person2)); //true

ECMAScript 5中增加了一個新方法 Object.getPrototypeOf() 返回 Prototype 的值。

alert(Object.getPrototypeOf(person1)==Person.prototype); //true
alert(Object.getPrototypeOf(person1).name); //"Nicholas"

雖然可以通過對象實例訪問原型中的值,但卻不能通過對象實例重寫原型中的值。在實例中添加的與原型重名的屬性,將覆蓋原型中的屬性,使用 delete 操作符可以完全刪除實例屬性,從而訪問原型屬性。如下所示:

function Person( ){
}
Person.prototype.name = "Nicholas";
}

var person1 = new Person( );
var person2 = new Person( );

person1.name = "Greg";
alert(person1.name);                  //"Greg"
alert(person2.name);                 //"Nicholas"

delete.person1.name;
alert(person1.name);                  //"Nicholas"

使用 hasOwnProperty( ) 方法(從Object繼承來)可以檢測一個屬性是否存在於實例中。如:

function Person( ){
}
Person.prototype.name = "Nicholas";
}

var person1 = new Person( );
alert(person1.hasOwnProperty("name"));     //false

person1.name = "Greg";
alert(person1.name);      //"Greg"
alert(person1.hasOwnProperty("name"));     //true

delete person1.name;
alert(person1.hasOwnProperty("name"));     //false

訪問原型和實例屬性

單獨使用 in 操作符

無論要訪問的屬性存在於實例還是原型中,都會返回 truth .例如:

function Person( ){
}
Person.prototype.name = "Nicholas";
}

var person1 = new Person( );

//同時使用hasOwnProperty()方法和in操作符可以確定該屬性在實例中還是原型中
alert(person1.hasOwnProperty( " name" ));          //false
alert("name" in person1);                          //true

person1.name = "Greg";
alert(person1.hasOwnProperty( " name" ));          //true

使用 for-in 循環

返回的是所有能夠通過對象訪問的、可枚舉(enumerated)的屬性,包括實例和原型中的屬性。覆蓋了原型中不可枚舉屬性的實例屬性也會在 for-in 循環中返回。

根據規定,所有開發人員定義的屬性(和函數)都是可枚舉的,只有IE8及更早版本中例外。IE早期版本中的bug使得覆蓋不可數枚舉的實例屬性不會再 for-in 循環中出現 。如:

var o = {
    //原型的 toString()方法的Enumerable 值爲false
    toString : function {
    return "My Object";
    }
};
for ( var prop in o) {
    if (prop == "toString") {        // 在IE中跳過Enumerable 值爲false的方法
    alert ( "Found toString !");     //在IE中不會顯示
    }
}

ECMAScript 也將 constructor property 屬性的 Enumerable 特性設置爲 false ,但並不是所有瀏覽器都按此實現。

Object.keys( ) 方法

取得對象上所有可枚舉的實例屬性( 不包含原型上的屬性),例如:

function Person( ){
}
Person.prototype.name = "Nicholas";
Person.prototype.age = "29";
Person.prototype.sayName = function ( ){
 alert ( this.name );
};

var keys = Object.keys(Person.prototype);
alert(keys);           //"name,age,sayName"

var person1=new Person();
Person1.name = "Mary";
var keys = Object.keys(person1);
alert(keys);           //"name,age"

Object.getOwnPropertyNames( ) 方法

獲得所有實例屬性,不管是否可枚舉,可使用。如:

var keys = Object.getOwnPropertyNames( Person.prototype);
alert(keys);                //"constructor , name, age, sayName"

Object.keys( ) Object.getOwnPropertyNames( ) 方法都可以替代 for-in 循環。支持這兩個方法的瀏覽器有 IE9+、Firefox 4+、Safari 5+、Opera 12+和Chrome。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章