阅读:对象的方法
总结:
- Object.getPrototypeOf(a) 得到a的原型
- Object.setPrototypeOf(a,b) 给对象a赋原型b
- Object.create(a) 创造一个和实例a有同样原型的实例。
- a.isPrototypeOf(b) 判断a是否为b的原型
- a.proto 得到a的原型
- a.getOwnPropertyNames() 得到a本身的属性所有键名,不包括继承的,不管可不可以遍历都能显示
- Object.keys(a) 只遍历a的自身的可以遍历的属性
- Object.prototype.hasOwnProperty() Date.hasOwnProperty(‘length’) // true 判断某个属性在自身还是在原型链
- 对象的拷贝
Object.getPrototypeOf()
返回对象的原型,是获取对象原型的标准方法
var F = function () {};
var f = new F();
Object.getPrototypeOf(f) === F.prototype // true
特殊:
// 空对象的原型是 Object.prototype
Object.getPrototypeOf({}) === Object.prototype // true
// Object.prototype 的原型是 null
Object.getPrototypeOf(Object.prototype) === null // true
// 函数的原型是 Function.prototype
function f() {}
Object.getPrototypeOf(f) === Function.prototype // true
Object.setPrototypeOf()
为参数设置原型:两个参数,一是现有对象,二是原型对象。
var a={};
var b={x:1};
Object.setPrototypeOf(a,b);
Object.getPrototypeOf(a)===b;//true
a.x//1
new命令可以用Object.setPrototypeOf方法模拟
var F=function(){
this.foo='bar';
}
var f=new F();
等同于:
Object.setPrototypeOf({},F.prototype);
F.call(f);
分为两步,第一步将空对象的原型设为构造函数的prototype属性;第二步是将构造函数内的this绑定这个空对象,使得定义在this上面的属性和方法都能转移到空对象上去。
以上两种方式步骤相同。
Object.create()
从一个实例对象生成另外一个实例对象
//原型对象
var A={
print:function(){
console.log('hello');
}
};
//实例对象
var B=Object.create(A);
Object.getPrototypeOf(B)===A//true
B.print()//hello
三种方式生成新对象等价:
var obj1 = Object.create({});
var obj2 = Object.create(Object.prototype);
var obj3 = new Object();
生成一个不继承任何属性的对象(没有toString和valueOf方法)
var obj=Object.create(null);
obj.valueOf()
//报错
使用Object.create方法的时候,必须提供对象原型,即参数不能为空,或者不是对象,否则会报错。
除了对象的原型,Object.create方法还可以接受第二个参数。该参数是一个属性描述对象,它所描述的对象属性,会添加到实例对象,作为该对象自身的属性。
Object.create方法生成的对象,继承了它的原型对象的构造函数。
Object.prototype.isPrototypeOf()
实例对象的这个方法用来判断该对象是否为参数对象的原型
var o1={};
var o2=Object.create(o1);
var o3 = Object.create(o2);
o2.isPrototypeOf(o3) // true
o1.isPrototypeOf(o3) // true
只要实例对象处在参数对象的原型链上,都会返回true。
Object.prototype.isPrototypeOf({}) // true
Object.prototype.isPrototypeOf([]) // true
Object.prototype.isPrototypeOf(/xyz/) // true
Object.prototype.isPrototypeOf(Object.create(null)) // false
上面代码中,由于Object.prototype处于原型链的最顶端,所以对各种实例都返回true,只有直接继承自null的对象除外。
Object.prototype.proto
返回该对象的原型,可读写
var obj={};
var p={};
obj._proto_=p;
Object.getPrototypeOf(obj)===p//true
根据语言标准,__proto__属性只有浏览器才需要部署,其他环境可以没有这个属性。应该尽量少用这个属性,而是使用Object.getPrototypeOf()和Object.setPrototypeOf(),进行原型的读写操作。
几个获取原型对象方法比较
如前所述,__proto__属性指向当前对象的原型对象,即构造函数的prototype属性。
var obj= new Object();
obj._proto_===Object.prototype //true
obj._proto_===obj.constructor.prototype//true
因此,获取实例对象obj的原型对象,有三种方法。
obj.proto
obj.constructor.prototype
Object.getPrototypeOf(obj)
第一种在除浏览器需要外的其他环境不部署,而obj.constructor.prototype在手动改变原型时可能会失效。所以在改变原型对象时一般要同时设置constructor属性。
推荐用第三种。
Object.getOwnPropertyNames()
返回一个数组,成员是参数对象本身的所有键名,不包含继承的属性键名(不管是否可以遍历)。只获取那些可以遍历的用Object.keys方法。
Object.keys(Date);//[]
表明Date对象所有自身属性都不能遍历。
Object.prototype.hasOwnProperty()
判断某个属性定义在自身还是原型链,是唯一一个处理对象属性不会遍历原型链的方法。
Date.hasOwnProperty('length') // true
Date.hasOwnProperty('toString') // false
in和for in
in表示一个对象是否具有某个属性,不区分是继承还是自身。
'length' in Date // true
'toString' in Date // true
获得对象所有可遍历的属性(不管自身的还是继承的),用for…in。
为了在for…in循环中获得对象自身的属性,可以采用hasOwnProperty方法判断一下。
for ( var name in object ) {
if ( object.hasOwnProperty(name) ) {
/* loop code */
}
}
对象的拷贝
确保拷贝后的对象,与原对象具有同样的原型。
确保拷贝后的对象,与原对象具有同样的实例属性。
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;
}
还没看懂。