Javascript: String.prototype.namespace.method и this

Уже длительное время хочется сделать как-то так:

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


Но к сожалению, на лицо проблема с this.

Если делать так:

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


Тогда каждый раз при 'one-'.utils().append('two') создается ненужный объект, да и не красиво это в конце концов.

Возможно ли переделать первый вариант так, что бы он работал?

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

Спасибо заранее!
  • Вопрос задан
  • 3993 просмотра
Решения вопроса 1
barmaley_exe
@barmaley_exe
Нельзя, т.к. Ваш объект utils не будет знать о контексте (this для него что-то неопределенное).
Но если хочется извращений, то можно
 // 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('!'));
(протестировано в Опере и Node.js)


Как видно, здесь активно используются геттеры, которые работают (вроде как) во всех современных браузерах, за исключением всего семейства IE.
Но самая большая печаль — ужасная неоптимальность этого кода. Вы только посмотрите на 3 (!!!) вложенных функции. И это я еще применил грязный хак с кешированием this в переменной self, дабы не создавать новых объектов.
Ответ написан
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы
RealtimeBoard Пермь
от 90 000 до 140 000 руб.
Smartbics Нижний Новгород
от 50 000 до 70 000 руб.
17 февр. 2019, в 05:00
200000 руб./за проект
17 февр. 2019, в 02:41
3000 руб./за проект
16 февр. 2019, в 23:24
6000 руб./за проект