javascripthtmlgetter-setterecmascript-5defineproperty

Clarification needed for implementing properties with the revealing module pattern using Html5 getters and setters


I've searched a lot for how to do properties in JavaScript. Most all of the revealing module pattern I've seen has exclusively exposed functions, and from experience I know if I expose an object, I'm only really getting a copy of the value right there and then, thus simply I could have a function getMyThing() and setMyThing and expose that. However I'm wanting to expose real properties

I've seen the old-school defineGetter which I'm avoiding and the newer Object.defineProperty( which I had some real troubles with. (I could easily use it against an arbitrary object but not THIS inside my "module" nor a property inside my module I wanted to reveal.

var myobj = (function() {  
    var name = "default name"
    var sayName = function() { return "hello " + name }
  return {
   badname : name, //this won't change
   sayName : sayName,
   get name() { return name;},
   set name(value) { name = value ;}
   
  }
})()
alert("should be default because its just a copy: " + myobj.badname)
alert("should be default: " + myobj.name)
myobj.name = "karl"
alert("should be default because its just a copy: " + myobj.badname)
alert("should be karl: "  + myobj.name)

Anyhow I see in a few places you can use get and set keywords and I have the following example that is working for me at least in Firefox and ie10.

My question: Is this an acceptable approach or are there hidden gotchas I am not aware of. Is it the approach that would be most accepted in modern browsers? What is this feature called? and what is the official name of the Object.defineProperty feature? I'm presuming the use of the get and set keyword is ECMAScript5 getters and setters, but what is the other one called?

and is the get and set keywords what is mentioned in this compatibility chart http://kangax.github.io/es5-compat-table/ under the category "Getter in property initializer" and "Setter in property initializer"?

example on JSfiddle - http://jsfiddle.net/klumsy/NagbE/1/


Solution

  • The pattern you're using looks good. It'll be supported by all ES5 browsers.

    The get and set syntax inside the object literal is often referred to as ES5 object literal extensions for defining accessor properties. An accessor property is a property that is made up of a getter and/or setter. The term for the traditional kind of property which isn't a getter/setter is a data property.

    And, yes, that is what kangax's compatibility table is referring to by "... in property initializer" (if you mouse-over the grey "c" with a circle around it on that page, you can see the actual test that's being run).

    The meta-property features provided by Object.defineProperty are referred to as property descriptors. There are two kinds of property descriptors in ES5: data descriptors and accessor descriptors, which are made up of the following descriptor properties:


    Data Descriptor: value, writable, enumerable, configurable

    Example:

    Object.defineProperty(obj, 'prop', {
        value: 'some value',
        writable: true,
        enumerable: false,
        configurable: true
    });
    

    Accessor Descriptor: get, set, enumerable, configurable

    Example:

    Object.defineProperty(obj, 'prop', {
        get: function() { return 'foo'; },
        set: function() { /* do something... */ },
        enumerable: false,
        configurable: true
    });