该新特性属于 ECMAScript 2015(ES6)规范,在使用时请注意浏览器兼容性。
概述
将一个指定的对象的原型设置为另一个对象或者null(既对象的[[Prototype]]内部属性).
语法
Object.setPrototypeOf(obj, prototype)
参数
- obj
- 将被设置原型的对象.
- prototype
- 该对象新的原型(可以是一个对象或者
null).
描述
如果对象的[[Prototype]]被修改成不可扩展(通过 Object.isExtensible()查看),就会抛出 TypeError异常。如果prototype参数不是一个对象或者null(例如,数字,字符串,boolean,或者 undefined),则什么都不做。否则,该方法将obj的[[Prototype]]修改为新的值。
Object.setPrototypeOf()是ECMAScript 6最新草案中的方法,相对于 Object.prototype.__proto__ ,它被认为是修改对象原型更合适的方法
示例
var dict = Object.setPrototypeOf({}, null);
Polyfill
我们必须借助非标准的 Object.prototype.__proto__才能实现这个方法.
//chrome和火狐中有效,IE无效
Object.setPrototypeOf = Object.setPrototypeOf || function (obj, proto) {
obj.__proto__ = proto;
return obj;
}
添加原型链
通过Object.getPrototypeOf()和 Object.prototype.__proto__的组合,可以给一个新的原型对象添加完整的原型链
/**
*** Object.appendChain(@object, @prototype)
*
* Appends the first non-native prototype of a chain to a new prototype.
* Returns @object (if it was a primitive value it will transformed into an object).
*
*** Object.appendChain(@object [, "@arg_name_1", "@arg_name_2", "@arg_name_3", "..."], "@function_body")
*** Object.appendChain(@object [, "@arg_name_1, @arg_name_2, @arg_name_3, ..."], "@function_body")
*
* Appends the first non-native prototype of a chain to the native Function.prototype object, then appends a
* new Function(["@arg"(s)], "@function_body") to that chain.
* Returns the function.
*
**/
Object.appendChain = function(oChain, oProto) {
if (arguments.length < 2) {
throw new TypeError('Object.appendChain - Not enough arguments');
}
if (typeof oProto === 'number' || typeof oProto === 'boolean') {
throw new TypeError('second argument to Object.appendChain must be an object or a string');
}
var oNewProto = oProto,
oReturn,
o2nd,
oLast;
oReturn = o2nd = oLast = oChain instanceof this ? oChain : new oChain.constructor(oChain);
for (var o1st = this.getPrototypeOf(o2nd);
o1st !== Object.prototype && o1st !== Function.prototype;
o1st = this.getPrototypeOf(o2nd)
) {
o2nd = o1st;
}
if (oProto.constructor === String) {
oNewProto = Function.prototype;
oReturn = Function.apply(null, Array.prototype.slice.call(arguments, 1));
this.setPrototypeOf(oReturn, oLast);
}
this.setPrototypeOf(o2nd, oNewProto);
return oReturn;
}
使用
例子一:给一个原型添加链
function Mammal() {
this.isMammal = 'yes';
}
function MammalSpecies(sMammalSpecies) {
this.species = sMammalSpecies;
}
MammalSpecies.prototype = new Mammal();
MammalSpecies.prototype.constructor = MammalSpecies;
var oCat = new MammalSpecies('Felis');
console.log(oCat.isMammal); // 'yes'
function Animal() {
this.breathing = 'yes';
}
Object.appendChain(oCat, new Animal());
console.log(oCat.breathing); // 'yes'
例子二:将一个基本类型转化为对应的对象类型并添加到原型链上
function Symbol() {
this.isSymbol = 'yes';
}
var nPrime = 17;
console.log(typeof nPrime); // 'number'
var oPrime = Object.appendChain(nPrime, new Symbol());
console.log(oPrime); // '17'
console.log(oPrime.isSymbol); // 'yes'
console.log(typeof oPrime); // 'object'
例子三:给函数类型的对象添加一个链,并添加一个新的方法到那个链上
function Person(sName) {
this.identity = sName;
}
var george = Object.appendChain(new Person('George'), 'console.log("Hello guys!!");');
console.log(george.identity); // 'George'
george(); // 'Hello guys!!'
说明书
| 说明 | 状态 | 备注 | |
|---|---|---|---|
| ECMAScript 2015 (6th Edition, ECMA-262) Object.setProtoypeOf |
|
Initial definition. |
浏览器兼容性
| Feature | Chrome | Firefox (Gecko) | Internet Explorer | Opera | Safari |
|---|---|---|---|---|---|
| Basic support | 34 | 31 (31) | 11 | (Yes) | 未实现 |
| Feature | Android | Chrome for Android | Firefox Mobile (Gecko) | IE Mobile | Opera Mobile | Safari Mobile |
|---|---|---|---|---|---|---|
| Basic support | 未实现 | 未实现 | 31.0 (31) | ? | 未实现 | 未实现 |