Object.create和new(类或构造函数)的区别

3
我正在尝试区分创建新对象的不同方式。基本上,您可以通过对象字面量(const obj = {};)创建新对象,作为某个类的成员(const obj = new MyObjClass;),作为构造函数的结果或通过调用Object.create()
JavaScript中的每个实体都是一个对象,甚至包括函数,因此一切都有.__proto__属性,但只有函数可能具有(也可能没有).prototype属性。子类的.__proto__属性等于其父类的.prototype属性。在这些函数的.prototype属性内部,您可能会找到.constructor()方法,当您使用“new”关键字调用这些函数时,该方法被调用。
对于类和构造函数,这适用:您调用new YourFunction(),然后返回一个新对象,它的__proto__指向父级的.prototype,同时调用.prototype.constructor(),它的工作是设置最终对象的属性和方法。
但是,如果您使用Object.create()而不是“new”关键字,是否可能完全重新创建“new”关键字的行为?
在这里,我尝试重新创建它,看起来它运行良好,但是当您console.dir()每个最终对象时,您会看到相当不同的结果。所以..
这些创建新对象的方法之间的核心区别是什么?有没有什么在表面下,还是只是个人偏好的问题?
const objStorage = {}; // just a storage variable so it is easy to pass it to console.dir()

const obj0 = {  // Declaring an object literal, so that we can pass it to Object.create()
  state: "inside Object.create()",
  showState() { console.log("State: " + this.state) }
}

function Obj1() {  // Making constructor function
  this.state = "inside constructor Function()";
  this.showState = function () { console.log("State: " + this.state) }
}

class Obj2 {  // Making class declaration
  constructor() {
    this.state = "inside Class";
    this.showState = function () { console.log("State: " + this.state) }
  }
}

const obj3 = function(){  // Trying to recreate class functionality, so that it can be used both ways
  let self = {};
  self.state = "inside self-made constructor";
  self.showState = function () { console.log("State: " + this.state) }
  return self
};
obj3.prototype = {};
obj3.prototype.constructor = obj3;

objStorage.a = Object.create(obj0); 
objStorage.b = new Obj1; 
objStorage.c = new Obj2; 
objStorage.d = new obj3.prototype.constructor; 
objStorage.e = Object.create(obj3()); 

objStorage.a.showState(); // State: inside Object.create()
objStorage.b.showState(); // State: inside constructor Function()
objStorage.c.showState(); // State: inside Class
objStorage.d.showState(); // State: inside self-made constructor
objStorage.e.showState(); // State: inside self-made constructor

你在谈论“child(子类)”和“parent(父类)”,但实际上应该是“instance(实例)”和“class(类)”。 - undefined
1个回答

4
Object.create()new 构造函数之间的主要区别是,虽然它们都使用传递的原型对象创建一个带有原型链的对象,但只有 new 运算符将新创建的对象作为 this 应用于构造函数,而 Object.create() 不会这样做。
以下是一些示例以说明这个区别的效果:

const a = new Array();
const b = Object.create(Array.prototype);

console.log(Array.isArray(a));
console.log(Array.isArray(b));

const c = new Map();
const d = Object.create(Map.prototype);

console.log(c.set('foo', 'bar'));
console.log(d.set('foo', 'bar'));

在大多数情况下,没有必要直接使用Object.create()。构造函数通常会初始化内部成员,这些成员对于对象正常工作是必要的。
回答你的另一个问题,不,new不能完全使用Object.create()重新创建,但是可以通过使用Reflect.construct()来实现。

1
Patrick,非常感谢! 我会尝试深入研究Reflect.construct(),但总体来说,现在看来Object.create()是为了其他目的而设计的.. Object.create()不会调用构造函数 - 这是主要的观点,我猜想 - undefined

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接