Chaining

#1

Я пытаюсь выполнить задачу - разбить строку на массив по разным разделителям. Хочу сделать двумя способами:

distinct(text).divide(’ ‘)
.divide(’-’)
.divide(’,’);

2. 
text.divide(' ')('-')(',');

В первом варианте у меня выявляется ошибка "TypeError: distinct(…).divide is not a function
Можете объяснить, в чем я не прав?

Во втором варианте я не знаю как саму строку указать

String.prototype.divide = separator => this.split(separator);
#2

Основная механика chain-нинга в том чтобы каждый метод возвращал такой объект, у которого можно вызвать методы (по этому принципу работает jQuery, например). Простая демонстрация механики:

function counter(initial) {
	let val = initial || 0
	return {
		inc() {
			val += 1
			return this
		},
		dec() {
			val -= 1
			return this
		},
		val() {
			return val
		}
	}
}

var i = counter(10)
i.inc().inc().dec().val()

Соответственно придумывай как использовать такую механику чтобы решить твою задачу.

Метод distinct вернул такой тип данных, у которого нет метода divide.

String.prototype.divide = separator => this.split(separator);

Две проблемы. Сама идея реализации не сработает. Из-за того что возвращаемое значение - это не функция, которую можно вызывать.

При этом реализация не работает как хотелось бы из-за того что в прототип записывается функция с “закрепленным” контекстом “this” (стрелочная функция). Нужно писать function, тогда в this будет строка.

String.prototype.withBold = function () {
	return `<b>${this}</b>`
}

'lol'.withBold()
2 Likes
#3

Первый вариант

const distinct = str => {
  let words = [].concat(str);

  return {
    divide(separator) {
      let temp = [];

      words.forEach(element => {
        temp = temp.concat(element.split(separator));
      });

      words = temp.splice(0, temp.length);
      return this;
    },

    valueOf() {
      return words;
    }
  };
};

function splitify(str) {
  return distinct(str)
    .divide(' ')
    .divide('-')
    .divide(',')
    .valueOf();
}
console.log(splitify('Hello World,I-am code'));
#4

Да, гуд

#5

Во втором варианте выявляется ошибка ReferenceError: Invalid left-hand side in assignment
Я вот что думаю, я пытаюсь строке присвоить массив. Наверное

str.div(' ')('-')(',').valueOf();

я не смогу сделать.

#6

ссылка нерабочая

#7

исправил

#8

this = this.split(separator);

Такая запись просто невалидна. this - это не место куда можно записать новое значение (только если this ссылается на какое-то место, как с объектами, то в то место можно записать новое свойство. В твоем случае this это примитив, и с ним работает передача данных по значению а не по ссылке).

1 Like
#9

Второй вариант

String.prototype.div = function(separator) {
  let words = this.split(separator);

  function chain(sep) {
    let temp = [];

    words.forEach(element => {
      temp = temp.concat(element.split(sep));
    });

    words = temp.splice(0, temp.length);
    return chain;
  }
  chain.valueOf = () => words;

  return chain;
};

function splitify(str) {
  return str.div(' ')('-')(',').valueOf();
}

console.log(splitify('Hello World,I-am code'));