在对象上正确设置原型构造函数

Set the prototype constructor correctly on an object

本文关键字:设置 原型 构造函数 对象      更新时间:2023-09-26

我有一个DTO类型,它实际上是键/值对的映射。为了简洁起见,我通常会为此使用对象文字,但这预示着将[[prototype]].constructor设置为有意义的值的结果对象。

例如

function MyDto() {
    var o = { 
        myProperty: null
    };
    return o; //[[prototype]].constructor is meaningless
}

有没有办法做类似的事情,但将 [[prototype]].constructor 属性设置为更有意义的MyDto(而不是Object)?

不太确定你想做什么。但这可能会有所帮助..

function MyDto() {
    var o = { 
        myProperty: null
    }; 
    Object.setPrototypeOf(o,MyDto.prototype);
    return o;
}
a = MyDto();
console.log(a);

为了使obj instanceof Foo工作,obj 的原型必须指向函数的 prototype 属性的值 ( Foo )。已经提出了几种方法,这是另一种方法:

使用 new 调用函数并返回this(隐式或显式)。如果您希望能够在没有new的情况下调用该函数(从您的问题中不太清楚),请在函数内部检查它是否使用 new 调用:

function MyDto() {
    if (!(this instanceof MyDto)) {
        return new MyDto();
    }
    Object.assign(this, {myProperty: null});
}

注意:constructor 属性在内部没有任何意义,仅对使用代码的开发人员有意义。

我想我不明白你的问题,但你可以试试这个:

o.constructor = MyDto;

这会将o的构造函数设置为 MyDto ,但在执行o instanceof MyDto时将不起作用。

如果这是你想要的,我的建议是你实例化MyDto:

function MyDto() {
    this.myProperty = null;
}
var o = new MyDto();
console.log(o instanceof MyDto);       // true
console.log(o.constructor === MyDto);  // true

编辑:如果您在函数中return,那么您将丢失对new实例的引用。在您的情况下,MyDto作为具有自己的属性的Object实例的工厂工作 myPropert .

编辑2:我仍然更喜欢另一种方式,但使用Object.create也有效:

function MyDto() {
    return Object.create(MyDto.prototype, {
        myProperty: {
            writable: true,
            configurable: true,
            value: null
        }
    });
}
new MyDto() instanceof MyDto;       // true
new MyDto().constructor === MyDto;  // true
你从

错误的方向接近这个。如果您希望new Class()的结果是真正的instanceof Class,只需扩展默认实例对象,而不是创建并返回一个新对象。

function Class () {
    _.extend(this, {
        property: 'value',
        // ...
    });
}

(上面的代码使用Lo-Dash函数_.extend()来保持你的代码简短和甜蜜。类似的实现可以在几乎所有实用程序库或更大的 JavaScript 框架中找到)。