Javascript-форум (https://javascript.ru/forum/)
-   Общие вопросы Javascript (https://javascript.ru/forum/misc/)
-   -   Замыкание. Умножение сохраненного параметра на переданный (https://javascript.ru/forum/misc/82211-zamykanie-umnozhenie-sokhranennogo-parametra-na-peredannyjj.html)

worldsering 01.04.2021 23:25

Замыкание. Умножение сохраненного параметра на переданный
 
Суть задачи в следующем:
Нужно написать функцию, которая принимает 1 параметр. При первом вызове, этот параметр запомнится , а при втором - умножает переданный параметр с тем, что передали первый раз и так можно делать до бесконечности.
const number5 = number(5);
const number10 = number5(2);
const number30 = number10(3);
number30(2) // 60  .... и так можно сколько угодно раз


Вот моя функция с замыканием, вполне себе просто, а главное хорошо работает, доп проверки мне ни к чему - этого нет в условии:
function math(value){
  let counter=1;
  return function(number){  
    return counter *= number;
  }  
}

Вот как она работает:
math(5) // 5
math(2) // 10
math(3) // 30


Но все таки мне нужно, что бы она работала по другому :
const number5 = math(5);
const number10 = number5(2); // и уже тут мне пишет, что number5 не функция .... и это логично, ведь мы ей присвоили значение от вызова math(5)
const number30 = number10(3);
number30(2) // 60  .... и так можно сколько угодно раз

Так вот как всё же сделать, что бы это работало так как мне надо, спасибо!


Подскажите, как это можно реализовать... спасибо

Aetae 02.04.2021 01:04

worldsering, напиши функцию, которая возвращает функцию. Посмотри на результат, и задавай вопросы если проблема ещё остаётся.

voraa 02.04.2021 08:44

Функции, возвращающие функции, которые возвращают функции...
А результат умножения как получить?

Vlasenko Fedor 02.04.2021 12:45

function math(value) {
    if (this.store === undefined) {
        this.store = value
    } else {
        this.store *= value
    }
    return this.store
}

console.log(math(5)) // 5
console.log(math(2)) // 10
console.log(math(3)) // 30

функция это объект
внутри объекта можно хранить значения

Nexus 02.04.2021 13:03

worldsering,
class Counter {
    constructor(initialValue = 1) {
        this.value = initialValue;
    }

    multiply(value) {
        return this.value *= value;
    }
}

var counter = (
    counter => counter.multiply.bind(counter)
)(new Counter(1));

console.log([
    counter(5) === 5,
    counter(2) === 10,
    counter(3) === 30,
    counter(2) === 60,
]);

Alexandroppolus 02.04.2021 13:11

Цитата:

Сообщение от voraa
А результат умножения как получить?

через valueOf

это старая избитая задача, где вся хитрость состоит в использовании valueOf для получения результата.

Ну и есть ещё одна тонкость - каждый вызов должен возвращать новую функцию, чтобы было иммутабельно, для переиспользования промежуточных результатов.

worldsering 02.04.2021 13:33

Спасибо, но это не работает так, как мне нужно ...
const number5 = math(5);
const number10 = number5(2); // и уже тут мне пишет, что number5 не функция
const number30 = number10(3);
number30(2) \\ уже естественно ничего не выдаст

worldsering 02.04.2021 13:35

Цитата:

Сообщение от Nexus (Сообщение 535140)
worldsering,
class Counter {
    constructor(initialValue = 1) {
        this.value = initialValue;
    }

    multiply(value) {
        return this.value *= value;
    }
}

var counter = (
    counter => counter.multiply.bind(counter)
)(new Counter(1));

console.log([
    counter(5) === 5,
    counter(2) === 10,
    counter(3) === 30,
    counter(2) === 60,
]);

Цитата:

Сообщение от Vlasenko Fedor (Сообщение 535138)
function math(value) {
    if (this.store === undefined) {
        this.store = value
    } else {
        this.store *= value
    }
    return this.store
}

console.log(math(5)) // 5
console.log(math(2)) // 10
console.log(math(3)) // 30

функция это объект
внутри объекта можно хранить значения

____________________________________________

Спасибо, но это не работает так, как мне нужно ...
const number5 = math(5);
const number10 = number5(2); // и уже тут мне пишет, что number5 не функция
const number30 = number10(3);
number30(2) \\ уже естественно ничего не выдаст

worldsering 02.04.2021 13:40

Цитата:

Сообщение от Alexandroppolus (Сообщение 535141)
через valueOf

это старая избитая задача, где вся хитрость состоит в использовании valueOf для получения результата.

Ну и есть ещё одна тонкость - каждый вызов должен возвращать новую функцию, чтобы было иммутабельно, для переиспользования промежуточных результатов.

__________________________________________________ _____
Не могу понять, для чего мне использовать valueOf ........
Можете подсказать как это применить на моём примере, только прежде, посмотрите пожалуйста сообщения выше, что бы вы точно поняли, что именно мне нужно ...
Спасибо

Alexandroppolus 02.04.2021 14:10

worldsering,
function number(num) {
    const inner = function(n) {
        const numberN = function(n1) {
            return inner(n * n1);
        }
        numberN.valueOf = function() { return n; };
        numberN.toString = function() { return String(n); };
        return numberN;
    }
    return inner(num);
}

const number5 = number(5);
const number10 = number5(2);
const number30 = number10(3);

const number15 = number5(3); // другая ветка умножения

alert([number5, number10, number30, number15, number10 + number15].join('\n'));

worldsering 02.04.2021 14:32

Цитата:

Сообщение от Alexandroppolus (Сообщение 535145)
worldsering,
function number(num) {
    const inner = function(n) {
        const numberN = function(n1) {
            return inner(n * n1);
        }
        numberN.valueOf = function() { return n; };
        numberN.toString = function() { return String(n); };
        return numberN;
    }
    return inner(num);
}

const number5 = number(5);
const number10 = number5(2);
const number30 = number10(3);

const number15 = number5(3); // другая ветка умножения

alert([number5, number10, number30, number15, number10 + number15].join('\n'));

__________________________________________________ ______
Спасибо но в итоге,
const number5 = number(5);
const number10 = number5(2);
console.log(number10(3)) // Выведет функцию, а не 30
console.log(number10(3).valueOf()) // Выведет 30

Можно ли как то это сделать без дополнительного метода valueOf.

Alexandroppolus 02.04.2021 14:39

Цитата:

Сообщение от worldsering
console.log(number10(3)) // Выведет функцию, а не 30

тут уж ничего сделать не получится.
если у тебя функция, то чем её не обвешивай, а всё равно она останется функцией, а не числом.
и console.log напишет о ней всю правду.

вероятно, эту проблему можно решить через Proxy, пока точно сказать не могу..

worldsering 02.04.2021 14:47

Цитата:

Сообщение от Alexandroppolus (Сообщение 535147)
тут уж ничего сделать не получится.
если у тебя функция, то чем её не обвешивай, а всё равно она останется функцией, а не числом.
и console.log напишет о ней всю правду.

вероятно, эту проблему можно решить через Proxy, пока точно сказать не могу..


Все равно спасибо большое ! очень помог!

destus 02.04.2021 14:50

Alexandroppolus,
вроде одна из вложенных функций лишняя
function number(num) {
    const numberN = function(n1) {
        return number(num * n1);
    }
    numberN.valueOf = function() {
        return num;
    };
    numberN.toString = function() {
        return String(num);
    };
    return numberN;
}

const number5 = number(5);
const number10 = number5(2);
const number30 = number10(3);

const number15 = number5(3); // другая ветка умножения

alert([number5, number10, number30, number15, number10 + number15].join('\n'));

Alexandroppolus 02.04.2021 14:54

destus,
Точно, с иннером я упоролся. Это фиаско.

Aetae 02.04.2021 18:53

Можно ещё then метод добавить, чтоб делать
const num = await number(1)(2)(3);

И toJSON чтоб в JSON.stringify работало.
:)


Часовой пояс GMT +3, время: 14:42.