Join MDN and developers like you at Mozilla's View Source conference, 12-14 September in Berlin, Germany. Learn more at https://viewsourceconf.org

Object.setPrototypeOf()

该新特性属于 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
Standard
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) ? 未实现 未实现

相关链接

文档标签和贡献者

 此页面的贡献者: inJs, xuzhijun, helm, teoli, ziyunfei
 最后编辑者: inJs,