Is it possible to combine javascript constructor function and object.create?

Update

If this is not possible, please feel free to give an answer explaining why. I would be happy to note how it was adopted.


I would simplify the following code a little (two steps to declare an “object” of an object, I would like to have one):

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'

I would like to create an entire prototype of a function in one shot using the constructor function that appears somewhere in Object.create. Maybe something like this:

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

However, when I call new Basher(), I get: 'TypeError: object is not a function'.

, ( ), , , , JS. : , Crockford, Ben Nadel, Joost Diepenmaat.

, , Object.create, . , , , .

, (Masher). - , ().

? .

+4
3

, - new, :

  • ( )
  • ( )

, JavaScript , (, , ES6 class), .prototype . , ( ):

function Class(p) {
    return (p.constructor.prototype = p).constructor;
}
var Casher = Class({
    constructor: function(opt) { this._name = opt.name },
    get name() { return this._name }
});
var foo = new Casher({name:'bar'});

Object.create ( , ).

, , Object.create, , ( , JS). , new - , create :

var Proto = { // some helper methods (usually native in more prototype-focused languages)
    clone: function() {
        return Object.create(this);
    },
    create: function(opt) {
        var derived = this.clone();
        derived.init(opt);
        return derived;
    },
    init: function(opt) {
        Object.getOwnPropertyNames(opt).forEach(function(p) {
            Object.defineProperty(this, p, Object.getOwnPropertyDescriptor(opt, p));
        }, this);
    }
};

var Pasher = Proto.create({ // "subclass" Proto
    init: function(opt) {
        if ("name" in opt) this._name = opt.name;
    },
    _name: "",
    get name() { return this._name; }
});
var foo = Pasher.create({name:'bar'});
+3

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"

, , 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

EDIT: new ; , . : var basher = Basher('Tom');.

0

, , , , , JS.

, :

var Lasher;

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

, , -, @Bergi , . -, , , ( , ). , . , () Lasher, prototype, - ( ).

, , . , Lasher ( ).

, . , :

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

, . Crasher () , Crasher , .

, Lasher , Masher () . , ().

, , Object.create , , , , JS . , Function , , , Object.create. .

, , , Object.create . , :

var Masher = function(){ console.log("default");};

Masher.prototype = Object.create(Object.prototype, {
    _name:  { writable: true },
    name:  { get: function() { return this._name;  }},
    constructor: { value: function(opts) {
        console.log("ctor");
        this._name  = opts.name;
    return this;
    }}
});
// "new Masher()" outputs:
// default
// undefined

, , / JS, , .

0
source

All Articles