Object.create与new操作符
前言
Object.create与new都可以用来生成一个对象,那么它们之间有什么区别和联系呢
分析
- 先看一下用法,很明显可以看出,
new
是生成一个基于构造函数生成一个新对象,而Object.create
是基于某个对象,将这个对象作为原型链实现的一个新的空对象。
function O(a) {
this.a = a;
}
const obj = new O(1); // { a: 1, [[Prototype]]: { constructor: f O(a), ... } }
const obj_new = Object.create(obj); // { [[Prototype]]: { a: 1, [[Prototype]]: { constructor: f O(a), ... } } }
-
从原理上来看,他们都存在一个原型链的继承,但是使用的场景和接受的对象是不太一致的。
new
是作用于一个构造函数,Object.create
接受一个将要被当做原型链的函数,最终得到的结果前者是一个已经初始化过后可能存在值的对象,但是后者肯定是个空对象。 -
接下来来模拟一下这两个方法的实现。
const my_new = function(fn, ...args) {
const obj = {}; // 创建一个空对象
const result = fn.apply(obj, args); // 把空对象当做this执行构造函数
obj.__proto__ = fn.prototype; // 把空对象的原型链指向构造函数
if (result) { // 判断是否构造函数已经有返回值,有就返回该构造函数的返回值
return result;
}
return obj; // 没有就把新生成的对象返回
}
const my_create = function (obj) {
const F = function() {}; // 构建一个空的构造函数
F.prototype = obj; // 将构造函数的原型链指向目标对象
return my_new(F); // 返回该构造函数生成的新对象
}
const obj = my_new(O, 1); // { a: 1, [[Prototype]]: { constructor: f O(a), ... } }
const obj_new = my_create(obj); // { [[Prototype]]: { a: 1, [[Prototype]]: { constructor: f O(a), ... } } }
小结
两者都体现了js的原型链继承的特点,只不过分别继承的对象不太一致,一个是原型链继承构造函数,一个是原型链继承目标对象,仅此而已。