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

Как заставить 'reduce' изменять 'this' а не возвращать новый объект?

Здравствуйте! Разбираюсь немного с объектами и this, и никак не могу понять как решить следующую проблему:

1. У нас есть некий массив с объектами под названием 'beers'

var beers = [ {}, {}, ... другие объекты массива ];


2. Добавляем методы к beers:
beers.reduceBeers = function () {
			 this.reduce(function (all, item, index) {
				if (item.locale === 'domestic') {
					all.push(item);
				}
				return all;
			}, []);
			return this;
		};
    
    beers.logBeers = function () {
        console.log(this);
        return this;
        };

    beers.otherBeers = function () {
        console.log('some other method that doing something with beers');
        return this;
	};


3. В итоге нам нужно, чтобы могли делать цепные вызовы этих методов
beers.reduceBeers().logBeers().otherBeers();

Для того, чтобы делать цепные вызовы мы должны возвращать 'this' после каждого выполнения метода. Но в методе beers.reduceBeers мы не изменяем сам массив beers (так как reduce возвращает новый ) и this просто возвращает beers без изменений. И следующий метод будет применятся к изначальному массиву beers, а не к отсортированному, с применением reduce. То есть нужно что-то вроде "this = this.reduce(function ... " но так делать нельзя, выдает ошибку. А если возвращать что-то другое, а не this, то следующий метод в цепочке (logBeers в нашем случае) просто не будет работать.

Буду очень благодарен если кто-то подскажет как это можно решить, единственное что пришло в голову это добавлять методы в Array.prototype но это как я читал очень нежелательно делать, особенно в таком случае как у меня...
  • Вопрос задан
  • 287 просмотров
Подписаться 1 Оценить 2 комментария
Решения вопроса 2
@zemka99
Если у вас есть возможность поменять структуру переменной beers и сделать вот так
var beers ={
		array:[{
			...
		},{
			...
		},{
			..
		}]
	};

то дальше можно без проблем работать с this.array
beers.reduceBeers = function(){
		this.array = [];
		this.array.reduce(function (all, item, index) {
			if (item.locale === 'domestic') {
				this.array.push(item);
			}
			return this.array;
		}, []);
		return this;
	};

вроде должно сработать
Ответ написан
DIITHiTech
@DIITHiTech
Fullstack javascript developer
var beers=[1,{locale:'domestic'},5,6,{locale:'domestic'},0,{locale:'domestic'}];

       beers.reduceBeers = function () {

           var stack=[];

           this.forEach(function(item,index){
               if (item.locale === 'domestic') {
                   stack.push(item);
               }
           });

           this.length = 0;//empty an Array;

           this.push.apply(this,stack);

           return this;
       };

       beers.reduceBeers();


Насчет целесообразности reduce терзают смутные сомнения ... Хотя можете запихать в stack что хотите, все что в stack будет добавлено в "this". Тоже самое:
beers.reduceBeers = function () {

           var stack=this.filter(function(item,index){
                return item.locale === 'domestic';
           })

           this.length = 0;//empty an Array;
           this.push.apply(this,stack);
           return this;
       };
Ответ написан
Пригласить эксперта
Ответы на вопрос 2
hahenty
@hahenty
('•')
Вместо редюс Array.prototype.filter - https://developer.mozilla.org/en-US/docs/Web/JavaS...

В методе reduceBeers результирующий массив после фильтра удержать в переменную (filterResult, например), потом опустошить массив this.splice( 0, this.length );
Затем сделать this.concat( filterResult );
Ответ написан
Ronnie_Gardocki
@Ronnie_Gardocki
Я у мамы фронтендщик.
Почему бы не написать что-то такое:
beers.reduceBeers = function () {
return this.filter(function(el) {return el === 'domestic'});
};

Конкретно у вас ошибка в том, что вы на сам this никак не влияете. То что вы там юзаете reduce, это никак не затрагивает this за рамками самого reduce. Вот если бы вы юзали splice например, то тогда данные бы менялись.
В моем примере делается все тоже что и у вас, только правильным методом (тут явно нужен фильтр, а не редьюс, который юзается для всяких сумм и прочих вещей) и изменяется сам this, который тут же возвращается.
Ответ написан
Ваш ответ на вопрос

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

Похожие вопросы