Search code examples
javascriptecmascript-5

Object.create instead of Constructors for inheritance


I want to be able to learn creating Objects per the new JavaScript ECMA 5 standards, and use them in my current projects, without breaking functionality. But I see un-explainable stuff that makes me afraid

Consider the following code:

var foo = {
        oldProp: 'ECMA Script 3',
        newProp: 'ECMA Script 5'
    };

// The new way of inheritance
var bar = Object.create( foo );

// and of assigning properties, if I am right
var bar2 = Object.create( Object.prototype, {
        oldProp: { value: 'ECMA Script 3'},
        newProp: { value: 'ECMA Script 5'}
    });

// and then
bar; 
// console output
Object {oldProp: "ECMA Script 3", newProp: "ECMA Script 5"}

// whereas !!
bar2;
Object {} // Why this?

Also,

bar.hasOwnProperty('oldProp');  // false, whereas
bar2.hasOwnProperty('oldProp'); // true !! It should be the other way round, right? 

Additionally, I am not able to change the property of bar2

bar2.oldProp = "Marry had a little lamb";
bar2.oldProp; // "ECMA Script 3"

And more --

for (k in bar2) console.log(bar2[k]) // undefined  

Am I creating the Objects in a correct way? What I basically want to achieve is getting rid of constructors.

Old code:

var Slideshow = function(type) {
    this.type = type;
    this.deleteSlideshow = function() {
        // some code
    }
}
Slideshow.prototype.nextSlide = function() {
    // lotsa code
}
var vanityFairSlideshow = new Slideshow('wide-screen');

I want to change to Object.create, may be kind of this:

var Slideshow = Object.create({ /* prototype */ }, { /* properties and methods */ });
var vanityFairSlideshow = Object.create( Slideshow , { /* properties and methods */ });

Whats the proper way of doing it?


Solution

  • Your problem here is the defaults for the descriptors (aside from value) that you omitted for each property.

    Using this syntax (like for defineProperty and defineProperties), writable is false by default, and enumerable is false.

    Setting both of these to true will result in the behaviour you expect.

    var bar2 = Object.create( Object.prototype, {
        oldProp: { value: 'ECMA Script 3', writable: true, enumerable: true}
    });
    

    http://jsfiddle.net/YZmbg/

    Also, hopefully you appreciate how this isn't supported in all browsers; note the compatibility table for Object.create. Shims which adhere to the writable and configurable properties do not, and cannot, exist.

    Finally, +1 for such a well written question; it's a breath of fresh air.