没有new或Object.create的原型继承

Prototypical inheritance without new or Object.create

本文关键字:原型 继承 create Object new 没有      更新时间:2023-09-26

是否有任何方法可以使对象从原型(1)继承而不使用new,以及(2)不使用Object.create。(我怀疑Object.create方法内部存在new,但在Firebug控制台告诉我它是本机代码之后,我怀疑它是本机的。)当我说"从原型继承"时,我的意思是真正的 JavaScript原型继承(即,不仅仅是模仿它)。当我看到它时,我知道真正的继承(即,__proto__属性存在,构造函数和原型之间存在循环引用,存在继承层次结构)。

我的问题归结为:即使'we hardly new ya', newObject.create是唯一的两种继承机制吗?

[…newObject.create是唯一的两种继承机制?

是的,他们是。至少这些是你唯一应该使用的。

可以直接赋值给__proto__,但它还不是一个标准属性。更多信息:MDN - __proto__ .

你可能知道newObject.create做一个隐藏的动作,我们可以调用setPrototype

Object.create = function(proto, properties) {
    var obj = {};
    setPrototype(obj, proto);
    Object.defineProperties(obj, properties);
    return obj;
}
function fakeNew(Constructor) {
    var obj = {};
    setPrototype(obj, Constructor.prototype);
    Constructor.call(obj);
    return obj;
}

不是"new is inside Object "。创建"或"对象。Create是在new里面。原型分配和其他操作都是这样。

实际上有一种实现setPrototype的方法,但你肯定知道它不是标准的。

function setPrototype(obj, proto) {
    obj.__proto__ = proto;
}

为了避免使用new操作符,但仍然实例化从原型(SomeClass的原型)继承的对象,一个简单的解决方案是构建一个facade构造函数(在幕后使用new操作符):

function SomeClassFacade() {
  return new SomeClass();
}
SomeClass.prototype = {
 /* ... */
};

从ES6开始,你也可以使用Reflect.construct,它的行为基本类似于new运算符:

function Constructor() {}
var instance = Reflect.construct(Constructor, []);
Object.getPrototypeOf(instance); // Constructor.prototype

如果你想要更接近Object.create的东西,ES6扩展类也可以创建继承,但只能从构造函数或null:

var obj = (class extends null{}).prototype;
delete obj.constructor;
Object.getPrototypeOf(obj); // null
function Constructor() {}
var obj = (class extends Constructor{}).prototype;
delete obj.constructor;
Object.getPrototypeOf(obj); // Constructor.prototype