Задача по введению в ООП: Контекст(this)

Доброго всем дня! Прошу помочь в следующей задаче:


Моё Решение.

const make = (numer, denom) => ({
   numer: numer,
   denom: denom,

   getNumer : function getNumer () { 
     return this.numer; 
    },
   getDenom  : function getDenom  () { 
     return this.denom; 
    },
    toString : function toString () {
      return toString(numer/denom);  
    },
    add : function add (rat1, rat2) { // 
      return (rat1 + rat2) = (rat1.getNumer * rat2.getDenom + rat1.getDenom * rat2.getNumer) / rat1.getDenom * rat1.getDenom;
    }
});

Проблема в методе add. Она явно написана неправильно…

Методы нужо вызывать: rat1.getNumer()

если вы про такой способ:
return (rat1 + rat2) = (rat1.getNumer() * rat2.getDenom() + rat1.getDenom() * rat2.getNumer()) / rat1.getDenom() * rat1.getDenom();
то он не проходит. Я проверил!

Что значит не проходит? Не проходит валидацию на сайте? Проверь по какой причине. Потому что без вызова методов у тебя ошибка концептуальная (код не работает как должен), а с вызовами скорее всего ошибка логическая - где-то в алгоритме или подходе.

Да, он не проходит по сайту. Там прописаны тесты, которые и проверяют решение. Вывод тестов показывает следующее:

make: Entering directory ‘/usr/src/app’
npm test -s

FAIL tests/rational.test.js

● Test suite failed to run

SyntaxError: /usr/src/app/rational.js: Invalid parenthesized assignment pattern (17:14)

  15 |     },
  16 |     add : function add (rat1, rat2) { // 
> 17 |       return (rat1 + rat2) = (rat1.getNumer() * rat2.getDenom() + rat1.getDenom() * rat2.getNumer()) / rat1.getDenom() * rat1.getDenom();
     |               ^
  18 |     }
  19 | });
  20 | 

  at Parser.raise (../../lib/node_modules/babel-jest/node_modules/@babel/parser/src/parser/location.js:41:63)

Test Suites: 1 failed, 1 total
Tests: 0 total
Snapshots: 0 total
Time: 1.721s
Ran all test suites.

make: *** [Makefile:2: test] Error 1

make: Leaving directory ‘/usr/src/app’

Это синтаксическая ошибка.

Нужно писать return = (rat1.getNumer() * rat2.getDenom() ...

Попробовал сделать так( с равно ошибка ):

return (rat1.getNumer() * rat2.getDenom() + rat1.getDenom() * rat2.getNumer()) / rat1.getDenom() * rat1.getDenom();

Вывод:

make: Entering directory ‘/usr/src/app’
npm test -s

FAIL tests/rational.test.js

✕ rational (10ms)

● rational

RangeError: Maximum call stack size exceeded

  11 |      return this.denom; 
  12 |     },
> 13 |     toString : function toString () {
     |                ^
  14 |       return toString(numer/denom);  
  15 |     },
  16 |     add : function add (rat1, rat2) { // 

  at toString (rational.js:13:16)
  at toString (rational.js:14:14)
  at toString (rational.js:14:14)
  at toString (rational.js:14:14)
  at toString (rational.js:14:14)
  at toString (rational.js:14:14)
  at toString (rational.js:14:14)
  at toString (rational.js:14:14)
  at toString (rational.js:14:14)
  at toString (rational.js:14:14)

Test Suites: 1 failed, 1 total
Tests: 1 failed, 1 total
Snapshots: 0 total
Time: 1.248s, estimated 2s
Ran all test suites.

make: *** [Makefile:2: test] Error 1

make: Leaving directory ‘/usr/src/app’

Это я натупил. Без = нужно писать. return (rat1.getNumer() * rat2.getDenom() ...

Ошибка-то да. Но это другая ошибка. Твоя задача (давай на ты, тут интернет - все свои) научиться понимать ошибки и действовать.

Эта ошибка про бесконечную рекурсию из-за поведения что toString внутри метода toString ссылается на функцию что определяет метод (т.е. сам на себя).

Еще вижу пару проблем в тсвоем решении. Думаю тебе чем починить свое решение, проще взять рабочее похожее и доделать до своего.

Хорошо, спасибо!
Я переделал код и вроде вышло неплохо. Но add всё равно не рабочий… Честно, не знаю, что с ним… ругается на rat2

Переделанный код:

function make(numer, denom) {
  return {
    numer: numer,
    denom: denom,

   getNumer : function() { 
    return this.numer; 
    },
   getDenom  : function() { 
    return this.denom; 
    },
    toString : function() {
     return `${numer}/${denom}`;  
    },
    add : function(rat1, rat2) { 
      return (rat1.getNumer() * rat2.getDenom() + rat1.getDenom() * rat2.getNumer()) / rat1.getDenom() * rat1.getDenom();
    }
  }
   
};

Вывод тестов:
TypeError: Cannot read property ‘getDenom’ of undefined

  16 |     },
  17 |     add : function(rat1, rat2) { 
> 18 |       return (rat1.getNumer() * rat2.getDenom() + rat1.getDenom() * rat2.getNumer()) / rat1.getDenom() * rat1.getDenom();
     |                                      ^
  19 |     }
  20 |   }
  21 |

Это значит что в переменной rat2 значение undefined. Это значит кто метод add был вызван без второго аргумента num.add(num1) примерно так.

Посмотри по условию задачи ожидает ли add 2 аргумента и всегда ли их два.

Да, заметил сейчас, что там один параметр. Думаю, как дальше решать… А кавычки нужны!

Бери значения из инстанса на котором вызывается метод а не из второго аргумента метода.

Не совсем понял, что ты имеешь ввиду? что такое "инстанса "?

Инстанс класса. Типа есть класс “Кот” и переменная “мурзик” в которую записан инстанс класса код.

Проще говоря делай this.getDenom() и this.getNumer()

Значит я правильно понял.

add : function(rat2) {
return (this.getNumer() * rat2.getDenom() + this.getDenom() * rat2.getNumer()) / this.getDenom() * this.getDenom();
}

Кстати, а вот ошибка!

TypeError: result.getNumer is not a function

  11 |   const rat2 = make(10, 3);
  12 |   const result = rat1.add(rat2);
> 13 |   expect(result.getNumer()).toBe(99);
     |                 ^
  14 |   expect(result.getDenom()).toBe(27);
  15 | 
  16 |   const rat3 = make(-4, 16);

Да

Ожидается что метод .add вернет новый объект рационального числа

да, это так! Только я понятие не имею, как это сделать:
Вот последний код. Я сделал методы геттерами, как в задании и просили. Для них по синтаксису не нужны у метода скобки ()

function make(numer, denom) {
return {
numer: numer,
denom: denom,

getNumer() {
return this.numer;
},
getDenom() {
return this.denom;
},
toString() {
return ${numer}/${denom};
},
add(rat2) {
return (this.getNumer * rat2.getDenom + this.getDenom * rat2.getNumer) / this.getDenom * this.getDenom;
}
}
};

Геттеры объявляются не так как ты написал. Ты написал объявления методов. Надо так.

get getNumber() {
   ...
}

Ты знаешь как сделать инстанс рационального числа. Для этого нужно число и деноминатор. Посчитай их в .add, создай из них инстанс и верни его из метода.

вот последняя версия кода:

function make(numer, denom) {
  return {
    numer: numer,
    denom: denom,

   get getNumer() { 
    return this.numer; 
    },
   get getDenom() { 
    return this.denom; 
    },
    get toString() {
     return `${numer}/${denom}`;  
    },
    add(rat2) {
       return new make(this.getNumer * rat2.getDenom + this.getDenom * rat2.getNumer) / this.getDenom * this.getDenom;
    }
  }
   
};