javascript 构造函数和object.create 可以结合使用吗?

And*_*ips 5 javascript constructor new-operator object-create

更新

如果这是不可能的,请随时提供解释原因的答案。我很乐意将其标记为已接受。


我想稍微简化以下代码(对象“声明”的两个步骤,我想要一个):

var Masher = function(opts) {
    this._name  = opts.name;
};

Masher.prototype = Object.create(Object.prototype, {
    _name:  { writable: true },
    name:  { get: function() { return this._name;  }}
});

// Note: (new Masher({name: 'bar'})).name == 'bar'
Run Code Online (Sandbox Code Playgroud)

我想一次性创建整个函数原型,构造函数出现在 Object.create 的某处。也许,像这样:

var Basher = Object.create(Function.prototype, {
    _name:  { writable: true },
    name:  { get: function() { return this._name;  }},
    constructor: { value: function(opts) { this._name = opts.name; }}
});
Run Code Online (Sandbox Code Playgroud)

但是,当我调用时new Basher(),我得到:'TypeError: object is not a function'。

虽然我意识到我可以用语法糖(一个帮助程序库)来做到这一点,但我的目标是让事情尽可能简单,并对 JS 对象、原型、构造函数内部结构有一些了解。我试图阅读尽可能多的内容:SO相关问题CrockfordBen NadelJoost Diepenmaat

也许我还没有找到正确的表述,或者我正在与 Object.create 的设计理念作斗争,或者语言不允许这样做。也许,这真的只是一种风格,因此,是一种自负。

当然,我可以接受两步过程(Masher)。将所有内容打包到一起感觉不错(Basher)。

有没有办法做到这一点?谢谢。

Nic*_*oud 0

Object.create()返回一个对象,而不是一个函数,并定义了特定的原型继承链。

var Basher = Object.create(Function.prototype, {
    _name:  { writable: true },
    name:  { get: function() { return this._name;  }},
    constructor: { value: function(opts) { this._name = opts.name; }}
});
> undefined
Basher
> Object {_name: undefined, name: (...)}_name: undefinedconstructor: function (opts) { this._name = opts.name; }name: (...)get name: function () { return this._name;  }__proto__: function Empty() {}
> typeof Basher
"object"
Run Code Online (Sandbox Code Playgroud)

但是,您可以组合Object.create()和 构造函数,以便将对象字面量重用为 API,这使代码看起来更简洁:

var basherAPI = {
    name: function () {
        return this._name;
    }
};

function Basher(name) {
    var inst = Object.create(basherAPI);
    // assign instance *state* here; the API is
    // reusable but each object needs its own state
    inst._name = name;
    return inst;
}

var basher = new Basher('Tom');
basher.name() // Tom
Run Code Online (Sandbox Code Playgroud)

编辑:在这种情况下,使用new关键字纯粹是约定;它与构造函数中发生的情况无关。也可以这样写:var basher = Basher('Tom');