A
A
Alexander Keith2011-04-28 22:20:46
JavaScript
Alexander Keith, 2011-04-28 22:20:46

Javascript: String.prototype.namespace.method and this

For a long time now I've been wanting to do something like this:

String.prototype.utils = {
        append : function(value){
            return this + value;
        }
}


But unfortunately, there is a problem with this .

If you do this:

String.prototype.utils = function(){
    
    var $this = this;
    return {
        append : function(value){
            return this + value;
        }
    }
}


Then every time 'one-'.utils().append('two') an unnecessary object is created, and it's not pretty after all.

Is it possible to remake the first option so that it would work?

'one-'.utils.append('two')

Thanks in advance!

Answer the question

In order to leave comments, you need to log in

1 answer(s)
[
[email protected]><e, 2011-04-28
@tenbits

It is impossible, because Your utils object won't know about the context (this is something undefined for it).
But if you want perversions, then you can

 // https://gist.github.com/947203
(function(){
  var _utils = { // String.prototype.utils
      append : function(tail){
        return this + tail;
      }
    },
    utils = {}, // фронтэнд. на этот объект будут навешены геттеры.
          // на _utils геттеры вешать нельзя т.к. тогда мы не сможем (вроде как) добраться до методов
    self = null, // тут будет контекст
    generateGetter = function(fnc){ // это геттер
      return function(){ // геттер возвращает функцию
          return function(){ // которая при вызове возвращает
              // результат применения соответствующего метода с нужным контекстом
              return _utils[fnc].apply(self, arguments);
            };
        };
    };

  for(var prop in _utils){  // смотрим все методы _utils
    if(_utils.hasOwnProperty(prop)){
      // и назначаем для них геттеры для нашего фронтэнд объекта
      utils.__defineGetter__(prop, generateGetter(prop));
    }
  }

  // Геттер на String.prototype, который вернет наш презентационный объект
  // Когда кому-нибудь захочется обратиться к какому-нибудь методу этого объекта,
  // обьявленному в _utils, он попадет на геттер
  String.prototype.__defineGetter__('utils', function(){
    self = this;
    return utils;
  });
})();

// Пример
console.log('Hello'.utils.append(' World'));
console.log('Hello'.utils.append(' World')
                   .utils.append('!'));
(tested in Opera and Node.js)

As you can see, getters are actively used here, which work (sort of) in all modern browsers, with the exception of the entire IE family.
But the biggest sadness is the terrible non-optimality of this code. Just look at 3 (!!!) nested functions. And I also applied a dirty hack with caching this in the self variable so as not to create new objects.

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question