5

Presume I have an object like this:

var Foo = {
  x: 5,
  sprite: new Image()
}

Problem: I want to initialize that sprite with the right src. However, when I use the following creation technique:

var f = Object.create(Foo);

I don't have a constructor method (aka init function) to setup sprite.src = 'cool.png';

My question:

If I am using the object literal technique, and Object.create(), when do I actually initialize some of my internal state (like the example of the new Image())

My solution:

var Foo = {
  create: function() {
    var f = Object.create(Foo);
    f.sprite.src = 'cool.png';
    return f;
  }
}

However, I don't know if that's a great pattern. I'd like to do this the "JavaScript Way" if there is a way. :)

Thanks!

hippietrail
  • 15,848
  • 18
  • 99
  • 158
Seth Ladd
  • 112,095
  • 66
  • 196
  • 279

5 Answers5

6

I do something very similar to what you've written above, but I combine it with the module pattern:

var Vehicle = (function(){
        var exports = {};
        exports.prototype = {};
        exports.prototype.init = function() {
                this.mph = 5;
        };
        exports.prototype.go = function() {
                console.log("Going " + this.mph.toString() + " mph.");
        };

        exports.create = function() {
                var ret = Object.create(exports.prototype);
                ret.init();
                return ret;
        };

        return exports;
})();

From the outside, this exposes Vehicle.create() and Vehicle.prototype. Then if I want to make a Derived type, I can do this:

var Car = (function () {
        var exports = {};
        exports.prototype = Object.create(Vehicle.prototype);
        exports.prototype.init = function() {
                Vehicle.prototype.init.apply(this, arguments);
                this.wheels = 4;
        };

        exports.create = function() {
                var ret = Object.create(exports.prototype);
                ret.init();
                return ret;
        };

        return exports; 

})();

This pattern lets me derive types without making the error of Car.prototype = new Vehicle(), which is fail if my constructors take parameters.

Sean McMillan
  • 10,058
  • 6
  • 55
  • 65
4

As I can assume from this link you should do something like:

function ImgInstance(src){
    var img=new Image();
    img.src=src;
    return img;
}

Object.create(Foo, {sprite: {value: ImgInstance("url")}});
Eldar Djafarov
  • 23,327
  • 2
  • 33
  • 27
1

I think this article sums it up pretty nicely:

http://www.bennadel.com/blog/2184-Object-create-Improves-Constructor-Based-Inheritance-In-Javascript-It-Doesn-t-Replace-It.htm

dortzur
  • 1,666
  • 2
  • 16
  • 21
  • In fact this article refers to the following blog post, that actually **does** explain how to emulate constructors with Object.create : http://www.uxebu.com/blog/2011/02/object-based-inheritance-for-ecmascript-5/ – Lucas Cimon Nov 25 '14 at 23:12
0

I would simply do this:

function Image(src) {
    this.src = src;
}

function Foo() {
    this.x = 5;
    this.sprite = new Image('cool.png');
}
ChaosPandion
  • 77,506
  • 18
  • 119
  • 157
  • It should be mentioned that this requires the goode olde `new` keyword rather than an `Object.create`, and doesn't create the prototype chain that the OP wants. – user123444555621 Jan 31 '11 at 21:15
-10

To cut a long story short: Don't try. The basic idea of Object.create is avoiding constructor functions. You're better off using this good old pattern:

var Foo = function (url) {
    //this.sprite.src = url; //  This will overwrite the prototype's src
    this.sprite = new Image();
    this.sprite.src = url;
};
Foo.prototype = {
    x: 5,
    sprite: new Image() // do you really want this?
};

Then use new Foo instead of Object.create.

user123444555621
  • 148,182
  • 27
  • 114
  • 126
  • provide some arguments on why he shouldn't try it please – a0viedo Mar 27 '13 at 18:50
  • @a0viedo Basically because it adds unnecessary confusion to your code. Each `Foo` instance would inherit a `create()` method that creates siblings. Why would anyone want this? – user123444555621 Mar 27 '13 at 20:51
  • With this construct, each Foo instance would inherit a create() method that creates children: function create() { return Object.create(this); } – rich remer Mar 20 '14 at 16:34