David Refoua
David Refoua

Reputation: 3617

Javascript getter using defineProperty for String returns null

I want to define a simple getter for String object in Javascript. I used to do the following: String.prototype.__defineGetter__("lowerCase", function() { return this.toLowerCase(); });

So, 'EXAMPLE'.lower would return 'example'.

However the __defineGetter__ method is depreacted. I tried to do:

Object.defineProperty(String, "lower", {
  get: function () {
    return this.toLowerCase();
  }
});

But, 'EXAMPLE'.lower will be null this way.

Am I missing something?

Upvotes: 0

Views: 1183

Answers (3)

trincot
trincot

Reputation: 350776

Two things:

  • You should define the getter on the prototype
  • If you plan to write 'EXAMPLE'.lower() with the parentheses, then the getter should not call the toLowerCase function, but return a reference to that function, since the calling part happens when you do .lower():

Object.defineProperty(String.prototype, "lower", {
  get: function () {
    return this.toLowerCase;
  }
});

console.log('EXAMPLE'.lower());

Alternative for when executing toLowerCase in the getter:

You should in total call the function toLowerCase just once. If you are planning to write 'EXAMPLE'.lower(), then those parentheses mean you call it there, so then you should not also call it in your getter. If you would do that, the getter would return the result string, and applying () to that will return an error. At that moment lower is not a method, but a non-function property.

So you could define lower as a non-function property, and then you should not call it like a function. So this also works:

Object.defineProperty(String.prototype, "lower", {
  get: function () {
    return this.toLowerCase(); // <-- call it here
  }
});

console.log('EXAMPLE'.lower); // <-- but then don't call it here!

Note that in both solutions the parentheses occur only once -- i.e. the place where you call toLowerCase. Having them twice makes no sense.

Upvotes: 1

afuous
afuous

Reputation: 1498

Use String.prototype instead of String. The way you are doing it, it will return String.toLowerCase(), which does not make sense. The getter must be defined on the prototype, not on the class, like you did in your first attempt with __defineGetter__.

Upvotes: 1

gurvinder372
gurvinder372

Reputation: 68413

Replace the first line

Object.defineProperty(String, "lower", {

by

Object.defineProperty(String.prototype, "lower", { //notice that you are making a change in prototype rather than String directly.

Upvotes: 1

Related Questions