Object.create 以及 Object.setPrototypeOf

第一部分

  Object.crate() 方法是es5中的关于原型的方法, 这个方法会使用指定的原型对象以及属性去创建一个新的对象

 

语法

  Object.create(proto, [ propertiesObjecy ])

参数

  proto

  必须的。一个对象,它是新创建的对象的原型

  

  propertiesObject

  可选的。 该参数是一组属性和值,该对象的属性名称将是新创建的对象的属性名称,值是属性描述符, 这些属性描述符的结构与Object.defineProperties()的第二个参数一样。 注意:该参数对象不能是 undefined,另外只有该对象中自身拥有的可枚举的属性才有效,也就是说该对象的原型链上属性是无效的。

抛出异常

如果 propertiesObject 参数不是 null 也不是对象,则抛出一个 TypeError 异常。

例子

 

     使用 Object.create 实现类式继承。

     下面的例子演示了如何使用Object.create()来实现类式继承。这是一个单继承。

//Shape - superclass
function Shape() {
  this.x = 0;
  this.y = 0;
}

Shape.prototype.move = function(x, y) {
    this.x += x;
    this.y += y;
    console.info("Shape moved.");
};

// Rectangle - subclass
function Rectangle() {
  Shape.call(this); //call super constructor.
}

// subclass extends superclass
Rectangle.prototype = Object.create(Shape.prototype);
Rectangle.prototype.constructor = Rectangle;

var rect = new Rectangle();

console.log('Is rect an instance of Rectangle?',
  rect instanceof Rectangle); // true
console.log('Is rect an instance of Shape?',
  rect instanceof Shape); // true

rect.move(1, 1); //Outputs, "Shape moved."

 这里的继承还是很好理解的,值得注意的是,使用这种方式继承,不会出现new。   

常见问题: Object.create(null) 和 {} 区别是什么

  在vue源码中,就会经常出现 Object.create(null)。 这样的结果就是 Object.create(null)创建的对象是不会以Object的原型为构造函数的,因为这个对象就没有原型。

console.log(Object.create({}).toString);   // function toString() { [native code] }
console.log(Object.create(null).toString); // undefined

使用 Object.create 的 propertyObject 参数

var o;

// 创建一个原型为null的空对象
o = Object.create(null);


o = {};
// 以字面量方式创建的空对象就相当于:
o = Object.create(Object.prototype);


o = Object.create(Object.prototype, {
  // foo会成为所创建对象的数据属性
  foo: { 
    writable:true,
    configurable:true,
    value: "hello" 
  },
  // bar会成为所创建对象的访问器属性
  bar: {
    configurable: false,
    get: function() { return 10 },
    set: function(value) {
      console.log("Setting `o.bar` to", value);
    }
  }
});


function Constructor(){}
o = new Constructor();
// 上面的一句就相当于:
o = Object.create(Constructor.prototype);
// 当然,如果在Constructor函数中有一些初始化代码,Object.create不能执行那些代码


// 创建一个以另一个空对象为原型,且拥有一个属性p的对象
o = Object.create({}, { p: { value: 42 } })

// 省略了的属性特性默认为false,所以属性p是不可写,不可枚举,不可配置的:
o.p = 24
o.p
//42

o.q = 12
for (var prop in o) {
   console.log(prop)
}
//"q"

delete o.p
//false

//创建一个可写的,可枚举的,可配置的属性p
o2 = Object.create({}, {
  p: {
    value: 42, 
    writable: true,
    enumerable: true,
    configurable: true 
  } 
});

 

第二部分

  Object.setPrototypeOf() 方法设置一个指定的对象的原型 ( 即, 内部[[Prototype]]属性)到另一个对象或  null

  

语法:

Object.setPrototypeOf(obj, prototype)

参数

obj
要设置其原型的对象。.
prototype
该对象的新原型(一个对象 或 null).


示例

var dict = Object.setPrototypeOf({}, null);

 

 一个例题:

    

其中的第一个题为true还是不难理解的, 开始这个对象obj的原型是 {name: "king"},然后因为是传递了引用,接着把原型又赋值给了null,但是呢,他们的地址没有变,还是在老地方,只是原型发生了变化。

原文地址:https://www.cnblogs.com/zhuzhenwei918/p/6843549.html