Задать вопрос

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')

Спасибо заранее!
  • Вопрос задан
  • 4093 просмотра
Подписаться 3 Оценить Комментировать
Помогут разобраться в теме Все курсы
  • Яндекс Практикум
    Фронтенд-разработчик расширенный
    13 месяцев
    Далее
  • Академия Eduson
    Fullstack-разработчик на JavaScript
    11 месяцев
    Далее
  • Skillbox
    JavaScript
    3 месяца
    Далее
Решения вопроса 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, дабы не создавать новых объектов.
Ответ написан
Пригласить эксперта
Ваш ответ на вопрос

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

Похожие вопросы
ITK academy Нижний Новгород
от 50 000 до 90 000 ₽
ITK academy Казань
от 50 000 до 90 000 ₽