構造函數、原型對象、實例對象之間的關係錯綜複雜,關於它們的屬性和方法不少,長得也很像。這裏概括出來,方便記憶和查閱。segmentfault
[[Configurable]]
:表示可否經過delete刪除屬性從而從新定義屬性、可否修改屬性的特性、可否把屬性修改成訪問器屬性。默認值爲true
。[[Enumerable]]
:表示是否可枚舉。默認值爲true
。[[Writable]]
:表示可否修改屬性的值。默認值爲true
。[[Value]]
:包含屬性的數據值,在這裏讀寫屬性。默認值爲undefined
。數組
修改屬性的特性:Object.defineProperty()
、Object.defineProperties()
。調用這兩個方法時,若是不指定,configurable
、enumerable
、writable
特性的默認值都是false
。函數
//定義一個屬性 var person = {}; Object.defineProperty(person, 'name', { value: 'hiyohoo', configurable: true, enumerable: true, writable: true }); //定義多個屬性 var person = {}; Object.defineProperties(person, { name: { value: 'hiyohoo' }, age: { value: 24, configurable: true, writable: true } });
獲取屬性的特性:Object.getOwnPropertyDescriptor()
只能用於實例屬性,要取得原型屬性的描述符,須要在原型上使用該方法。this
var descriptor = Object.getOwnPropertyDescriptor(person, 'age'); alert(descriptor.writable); //true
[[Configurable]]
[[Enumerable]]
[[Get]]
:讀取屬性時調用該函數。默認值爲undefined
。[[Set]]
:寫入屬性時調用該函數。默認值爲undefined
。prototype
訪問器屬性不能直接定義,必須使用Object.defineProperty()
來定義。訪問器屬性經常使用於改變該屬性,其餘屬性也會變化的狀況。code
var book = { _year: 2004, //屬性前面的下劃線記號經常使用於表示只能經過對象方法訪問的屬性。 edition: 1 }; Object.defineProperty(book, 'year', { get: function() { return this._year; }, set: function(newValue) { if (newValue > 2004) { this._year = newValue; this.edition += newValue - 2004; } } }); book.year = 2016; console.log(book.edition); //13
如下的屬性和方法均如下面的代碼爲例:對象
var Person = function(name) { this.name = name; }; Person.prototype.school = 'HNU'; Person.prototype.sayName = function() { return this.name; }; var person = new Person('hiyohoo');
prototype
指向原型對象,包含全部被實例共享的屬性和方法。繼承
console.log(Person.prototype); //Person{}
constructor
指向構造函數。ip
console.log(Person.prototype.constructor === Person); //true
isPrototypeOf()
判斷實例與原型之間的關係。原型鏈
console.log(Person.prototype.isPrototypeOf(person)); //true
constructor
沿着原型鏈找到原型中的constructor
屬性,最終指向構造函數。
console.log(person.constructor === Person); //true
__proto__
Firefox、Safari、Chrome支持這個屬性,指向原型對象。
console.log(person.__proto__ === Person.prototype); //true
hasOwnProperty()
從Object
中繼承而來,判斷屬性是不是實例的私有屬性,而不是繼承而來的共享屬性。
console.log(person.hasOwnProperty('name')); //true console.log(person.hasOwnProperty('school')); //false
Object.getPrototypeOf()
ECMAScript 5
中新增的方法,返回實例的原型。
console.log(Object.getPrototypeOf(person)); //Person{}
Object.keys()
ECMAScript 5
中新增的方法,返回一個包含全部可枚舉實例屬性的字符串數組。
console.log(Object.keys(person)); //["name"] console.log(Object.keys(Person.prototype)); //["school", "sayName"]
Object.getOwnPropertyNames()
返回全部實例屬性,不管是否可枚舉。
console.log(Object.getOwnPropertyNames(person)); //["name"] console.log(Object.getOwnPropertyNames(Person.prototype)); //["constructor", "school", "sayName"]
delete
刪除一個configurable
爲true
的私有屬性。
delete person.name; delete person.school; console.log(person.name); //undefined console.log(person.school); //HNU
for-in
返回全部可以訪問到的屬性。
for (p in person) { console.log(p); //name school sayName }
in
對象可以訪問到屬性時返回true
console.log('name' in person); //true console.log('sayName' in person); //true console.log('age' in person); //false
同時使用hasOwnProperty()
方法和in
操做符,能夠肯定一個屬性是存在於對象中仍是存在於原型中。
function isPrototypeProperty(object, name) { if (!(name in object)) { return ("Can't find " + '"' + name + '"'); } else if (object.hasOwnProperty(name)) { return false; } else { return true; } } console.log(isPrototypeProperty(person, 'name')); //false console.log(isPrototypeProperty(person, 'school')); //true console.log(isPrototypeProperty(person, 'age')); //Can't find "age"
instanceof
用於判斷一個對象是不是某個對象的實例。
console.log(person instanceof Person); //true console.log(person instanceof Object); //true
轉載請註明出處:http://www.javashuo.com/article/p-mvigwoal-bh.html
文章不按期更新完善,若是能對你有一點點啓發,我將不勝榮幸。