2
function t(){
}


let counter = t;

console.log(counter()); //1
console.log(counter()); //2
console.log(counter()); //3
console.log(counter()); //4
console.log(counter()); //5

Задача: Описать финкцию t , что бы при каждом вызове console.log() выводилось соответствующее значение после коментария. Для первого вызова - 1 , для 5ого - 5. Без использования глобальных переменных!! Весь код должен лежать в функции.

Мне кажется, всё дело в области видимости. Но я в этом не уверен и не знаю с чего мне начать. Укажите пожалуйста направление для мыслей! Спасибо

  • 2
    почитайте про замыкание –  Aug 22 '17 at 17:00
  • 1
    http://learn.javascript.ru/ - читать все. – Rostyslav Kuzmovych Aug 22 '17 at 17:00
  • Спасибо большое!!! – Someone NULL Aug 22 '17 at 17:02
  • 1
    Сдаётся мне, что 1. let counter = t; - должно быть не t, а t(). 2. "Весь код должен лежать в функции" - не совсем верное утверждение. Впрочем, можно выполнить и строго по условию, но, вероятно, получится немного не то, что хотят увидеть. UPDATE: при исправлении первого пункта второй теряет актуальность. – Qwertiy Aug 22 '17 at 17:06

4 Answers4

3

Ну раз уж ответ с тем, что нужно, запостили, запощу и ответ с тем, что НЕ нужно, зато полностью соответствует условию из вопроса:

function t() {
  var x = 1;
  counter = () => ++x;
  return x;
}

let counter = t;

console.log(counter()); //1 console.log(counter()); //2 console.log(counter()); //3 console.log(counter()); //4 console.log(counter()); //5

Qwertiy
  • 123,725
3

Справедливости ради, стоит заметить что задачу можно решить и одной функцией.

function t() {
   if (typeof t._counter !== 'number') {
      t._counter = 0
   }

return ++t._counter }

const counter = t

console.log(counter()) // 1 console.log(counter()) // 2 console.log(counter()) // 3 console.log(counter()) // 4 console.log(counter()) // 5

  • Эм.. Код в ответе ничего общего не имеет с named function expression. Чтобы было named function expression, надо var t = function t() { – Qwertiy Aug 22 '17 at 17:44
  • @Qwertiy А по-моему имеет самое непосредственное. Посмотрите на переменную counter. По-условию, ей присваивается функция, а не вызов. А согласно условию, место для для хранения переменных между вызовами остаётся только в объекте функции, к которому можно обратиться как раз по имени. – ReklatsMasters Aug 22 '17 at 17:48
  • 1
    t объявлена через function declaration, а не function expression и само имя t принадлежит внешнему скоупу, а не замыканию функции. Проверяется легко: после const counter = t можно добавить t = null и этот код упадёт. А вот если объявить t как var t = function t() {, то var t принадлежит внешнему скоупу, а function t - внутреннему (то самое named function expression), что обеспечит работоспособность кода при присваивании t = null снаружи. Собственно для этого оно и нужно. – Qwertiy Aug 22 '17 at 17:52
  • @Qwertiy Однако в задаче нет таких ограничений как t = null. Так что всё норм. А вот ссылку я может и очень хорошую подобрал. Суть же в том, что к функции по имени можно обратиться из неё самой. – ReklatsMasters Aug 22 '17 at 18:04
  • Да, с решением всё нормально - условию оно соответствует. Я только про неправильное пояснение говорил. – Qwertiy Aug 22 '17 at 18:33
2

Простой пример замыкания. И да, вместо t, должно быть t() по логике условия.

function t() {
  var i = 0;
  return function() {
    return ++i;
  }; 
}

var counter = t();

console.log(counter()); //1 console.log(counter()); //2 console.log(counter()); //3 console.log(counter()); //4 console.log(counter()); //5

edem
  • 5,970
0

Варианта с генератором еще нету?

const g = (function* (i){
    while(true) yield i++;
})(1);

function t(){ return g.next().value; }

let counter = t;

console.log(counter()); //1 console.log(counter()); //2 console.log(counter()); //3 console.log(counter()); //4 console.log(counter()); //5

Darth
  • 13,217