Damian Czapiewski
Damian Czapiewski

Reputation: 881

Namespaced object prototype

I'd like to enhance an object with some extra methods, for example add first() or second() methods to arrays but with a namespace so that it is called in the way [1, 2].item.second(), not [1, 2].second(). I got code like below but I'm getting undefined.

Array.prototype.item = {
    first: function () {
        return this[0];
    },
    second: function () {
        return this[1];
    }
};

[1, 2].item.second()
// undefined
// I don't want to use [1, 2].second()

Upvotes: 2

Views: 41

Answers (1)

haim770
haim770

Reputation: 49095

The this in your first() and second() functions refers to the item property of the array, not to the array itself and that's why you're getting undefined.

The easiest way would be to capture the correct context by turning item into a method, as follows:

Array.prototype.item = function() {
  var _this = this;

  return {
    first: function() {
      return _this[0];
    },
    second: function() {
      return _this[1];
    }
  };
};

Then:

[1, 2].item().first(); // 1
[1, 2].item().second(); // 2

As per your update, if you insist on the original property syntax, you can try the following:

Object.defineProperty(Array.prototype, 'item', {
  get: function() {
    var _this = this;

    return {
      first: function() {
        return _this[0];
      },
      second: function() {
        return _this[1];
      }
    };
  }
});

Then:

[1, 2].item.first(); // 1
[1, 2].item.second(); // 2

See MDN

Upvotes: 2

Related Questions