构造函数、原型对象、实例对象之间的关系错综复杂,关于它们的属性和方法不少,长得也很像。这里概括出来,方便记忆和查阅。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
文章不按期更新完善,若是能对你有一点点启发,我将不胜荣幸。