3

The following script DOES NOT WORK. What would be the proper way?

function AnObject () {
    get this.apple = () {
        return this.apple + "GET";
    }
    set this.apple = ( newValue ) {
        return newValue + "SET";
    }
}

var obj = new AnObject();
obj.apple = "Lemon";
console.log( obj.apple ); // LemonSETGET
1
  • What doesnt work about it? You never actually set the value in the set method. Commented May 10, 2015 at 15:33

4 Answers 4

5

You can use Object.defineProperties():

function AnObject() {
  Object.defineProperties(this, {
    apple: {
      get: function() {
        return this._apple + " GET";
      },
      set: function(value) {
        this._apple = value;
      },
      configurable: true, writable: true
    }
  });
 }

Note that you have to be careful to use a different property name if you want to keep the value around with the object directly. If not, you could use the constructor's closure:

function AnObject() {
  var theApple;

  Object.defineProperties(this, {
    apple: {
      get: function() {
        return theApple + " GET";
      },
      set: function(value) {
        theApple = value;
      },
      configurable: true, writable: true
    }
  });
 }
Sign up to request clarification or add additional context in comments.

Comments

3

To add to Pointy's ...point,

You can use getters and setters as a language feature, by putting them inside of Object Literals.

Your original constructor could be turned into a factory, with instance-based getters and setters simply by doing the following:

function makeAnObject () {
    var hiddenApple = "Granny Smith";
    return {
      get apple () { return hiddenApple; },
      set apple (ignore) { return hiddenApple; }
    };
}

var thing = makeAnObject();
thing.apple;
thing.apple = "Crab Apple";

Keep in mind that depending on getters/setters will flat-out explode on older browsers (IE8 being the real stickler here), used this way.

Also, using them inside of defineProperties is fine for preventing IE8 from exploding (as it's no longer a language construct)... ...buuuut, it doesn't actually add getters/setters, either (even with polyfills to add the method to Object, and not just DOM Elements), and thus, will have bugged behaviour, either due to syntax explosions, or due to doing something completely different from your other browsers.

This might not apply to you right now, and hopefully it never does... ...some of us still live in that horrible reality.

3 Comments

According to (developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/…) it has a broad support of IE9, Firefox 4, Chrome 5, Opera 11.6 and Safari 5.
Yes, it does. IE8, however, is the last version of IE on Windows XP. Places which have a lot of open-air software piracy (eg: China), still have a lot of people running IE8 (odd world; write mobile-only sites for some of the world's best smartphones, but if you want a desktop site, it's got to be IE8-compatible). As do companies that still haven't moved work PCs to Windows 7/8/10, and have locked down the browser. If you can afford to have your site 100% blow up and be completely unusable ( or test for IE LTE 8 and send them to browsehappy.com ), then go for it.
There are lots of great new features out there. There's no reason not to use them, when you know who your visitors are, and the 1% are worth ignoring (or telling they'd have a better experience on their old iPod Touch), but when it's 10% of paying customers, et cetera, you don't have that option. There are also polyfills and build tools to help run fancy new things in IE6-8; those tools just can't work as well, on some of the more low-level language features (proxies, weakmaps, getters/setters), 100% of the time, so some of the nicer features go unused, so that the majority can be.
1
class User {
  constructor(firstName, lastName) {
    this.firstName = firstName;
    this.lastName = lastName;
  }


  get fullName() {
    return `${this.firstName} ${this.lastName}`;
  }


  set fullName(newValue) {
    [this.firstName, this.lastName] = newValue.split(' ');
  }



};

let user = new User("AAAA", "BBBB");
alert( user.fullName ); 
user.fullName = "CCCC DDDD";
alert( user.fullName ); 

Comments

0

There are no setters and getters in JS

But you can emulate them

function AnObject () {
    var apple = '';
    this.get = function() {
        return apple + "GET";
    }
    this.set = function( newValue ) {
        apple = newValue + "SET";
    }
}

var obj = new AnObject();
obj.set("Lemon");
console.log( obj.get() ); // LemonSETGET

1 Comment

There are. They just require IE9+, and are defined in Object Literals (or in defineProperties). Also, they don't mask a property, you need to reference a different property/variable if you want to save something and retrieve it.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.