JavaScript为Object提供了很多方法,用来处理对象编程的相关操作。
1 Object.getPrototypeOf()
Object.getPrototypeOf 方法返回参数对象的原型,这是获取原型对象的标准方法,推荐使用。
var Person = function() {};
var p = new Person();
Object.getPrototypeOf(p) === Person.prototype // true
上面代码中,实例对象p的原型是Person.prototype。
2 Object.setPrototypeOf()
Object.setPrototypeOf 方法为参数对象设置原型,返回该参数对象。第一个参数是现有对象,第二个参数是原型对象。
var a = {};
var b = {x:1};
Object.setPrototypeOf(a, b);
Object.getPrototypeOf(a) === b // true
a.x // 1
上面代码中,Object.setPrototypeOf方法将对象a的原型,设置为对象b,因此a可以共享b的属性。
3 Object.create()
我们常常通过new命令调用构造函数来生成一个实例对象,但很多时候,只有一个实例对象,那怎么从一个实例对象,生成另一个实例对象呢?
Object.create方法可以解决这个问题,它接受一个对象作为输入,然后以它为原型,返回一个实例对象。该实例会完全继承原型对象的属性。
// 原型对象
var A = {
print: function() {
console.log('hello');
}
};
// 实例对象
var B = Object.create(A);
Object.getPrototypeOf(B) === A // true
B.print() // "hello"
B.print === A.print // true
上面代码中,Object.create以A为原型对象,生成了B实例对象。B继承了A的所有属性和方法。
Object.create方法的本质就是让新对象的prototype属性指向参数对象。
4 Object.prototype.isPrototypeOf()
实例对象的isPrototypeOf方法,用来判断该对象是否为参数对象的原型。
var obj1 = {};
var obj2 = Object.create(obj1);
var obj3 = Object.create(obj2);
obj2.isPrototypeOf(obj3) // true
obj1.isPrototypeOf(obj3) // true
obj3.isPrototypeOf(obj1) // false
上面代码中,obj1和obj2都是obj3的原型,因为它们都处于obj3的原型链。而obj3不是obj1的原型。
5 Object.getOwnPropertyNames()
Object.getOwnPropertyNames方法返回一个数组,成员是参数对象自身的所有属性的键名,不包含继承的属性键名。
Object.getOwnPropertyNames(Date)
// ["parse", "arguments", "length", ....]
上面代码中,Object.getOwnPropertyNames返回Date所有自身属性名,不管是否可以遍历。
如果只想获取那些可以遍历的属性,使用Object.keys方法。
Object.keys(Date) // []
上面代码表明,Date对象的所有自身属性,都是不可遍历的。
6 Object.prototype.hasOwnProperty()
hasOwnProperty方法用来判断某个属性是否属于对象自身。
Date.hasOwnProperty('length') // true
Date.hasOwnProperty('toString') // false
上面代码表明,length是Date自身属性,toString是继承属性。
7 in运算符和for...in循环
in运算符用来判断对象是否具有某个属性(不区分自身还是继承)。
'length' in Date // true
'toString' in Date // true
获得对象的所有可遍历属性,可以使用for...in循环。
var obj1 = {p1: 123};
var obj2 = Object.create(obj1, {
p2: {value:"abc", enumerable:true}
});
for (p in obj2) {
console.info(p);
}
// p2
// p1
上面代码中,obj2的p2属性是自身的,p1属性是继承的,都会被for...in遍历到。
如果只想获得对象自身属性,可以用hasOwnProperty判断一下。
for (var name in obj) {
if (Object.hasOwnProperty(name)) {
...
}
}
8 对象的拷贝
要完整拷贝一个对象,分成以下两步。
- 使拷贝后的对象,与原对象具有同样的原型。
- 使拷贝后的对象,与原对象具有同样的实例属性。
实现的对象拷贝函数如下:
function copyObject(orig) {
var copy = Object.create(Object.getPrototypeOf(orig));
copyOwnPropertiesFrom(copy, orig);
return copy;
}
function copyOwnPropertiesFrom(target, source) {
Object.getOwnPropertyNames(source).forEach(function(propKey) {
var desc = Object.getOwnPropertyDescriptor(source, propKey);
Object.defineProperty(target, propKey, desc);
});
return target;
}
注:本文适用于ES5规范,原始内容来自 JavaScript 教程,有修改。