Javascript-форум (https://javascript.ru/forum/)
-   Общие вопросы Javascript (https://javascript.ru/forum/misc/)
-   -   Вообще ничего не понял в этом коде... (https://javascript.ru/forum/misc/79917-voobshhe-nichego-ne-ponyal-v-ehtom-kode.html)

jaroslav.tavgen 07.04.2020 21:27

Вообще ничего не понял в этом коде...
 
Array.prototype.sum = function (...arguments){
    return this.reduce(arguments);
}
[1,2,3].sum((a,b)=>a+b);

Результат: TypeError: Cannot read property 'sum' of undefined с указанием на последнюю строчку.

Я, честно говоря, вообще не понял, что произошло:) Как так получилось, что массив стал считаться undefined?:)

voraa 08.04.2020 07:03

Поизучайте автовставку ';'

Array.prototype.sum = function (...arguments){
    return this.reduce(arguments);
};
[1,2,3].sum((a,b)=>a+b);

рони 08.04.2020 09:34

voraa,
чего то в супе коде не хватает. :)

voraa 08.04.2020 09:40

Цитата:

Сообщение от рони (Сообщение 522445)
voraa,
чего то в супе коде не хватает. :)

Я отвечаю на вопрос почему массив - undefined.
А с кодами (reduce, ...) - лучше человек сам поучится разбираться.

рони 08.04.2020 09:55

voraa,
почему бы не довести код, до рабочего состояния в целом?

voraa 08.04.2020 10:01

Цитата:

Сообщение от рони (Сообщение 522447)
voraa,
почему бы не довести код, до рабочего состояния в целом?

Array.prototype.sum = function (arguments){
    return this.reduce(arguments);
};
alert([1,2,3].sum((a,b)=>a+b));


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

рони 08.04.2020 10:12

Цитата:

Сообщение от voraa
Если я просто в коде уберу эти гребанные три точки, то этого мало.

ок, подождём пока код исправит автор темы.

jaroslav.tavgen 12.04.2020 11:55

Цитата:

Сообщение от voraa (Сообщение 522440)
Поизучайте автовставку ';'

Array.prototype.sum = function (...arguments){
    return this.reduce(arguments);
};
[1,2,3].sum((a,b)=>a+b);

Офигеть. То есть, если добавить точку с запятой, то этого аномального undefined нет.

А как это работает? Я прочитал про автоставку точки с запятой https://codeburst.io/ecmascript-auto...n-50f09091e377 , но до сих пор не понял, что меняет наличие или отсутствие точки с запятой после закрывающей скобки }

UPD: начинаю понимать. Дело в том. что [1,2,3]... идёт сразу после закрывающей фигурной скобки. Если в консоле Chrome в начале отдельно выполнить Array.prototype..., а потом отдельно [1,2,3]... , то undefined нет. В общих чертах начал понимать, но до конца пока неясно.

voraa 12.04.2020 12:32

В первом правиле говорится про токен-нарушитель. Тоесть нечто такое, что делает синтаксическую конструкцию недопустимой.

Но конструкция }[ - вполне допустима

Array.prototype.sum = function (...arguments){returnthis.reduce(arguments);}[1,2,3]

Мы описали какую то функцию. Функция - это объект. К объекту применима операция [] для получения свойства по имени.
[1,2,3] - тут используется операция ',', которая дает значение последнего из выражений (3)
Т.е приведенный выше пример пытается взять значение свойства с именем '3' у объекта функции. Такого нет, поэтому undefined/

Nexus 12.04.2020 12:39

jaroslav.tavgen, а что вы, собственно, сделать то пытаетесь?
На имплементацию метода «sum» это не похоже, на алиас базового метода «reduce» - тоже.

Хотите понять в чем у вас ошибка - дебажте, посмотрите, что у вас находится в переменной «arguments».

P.S. переопределять значение переменной «arguments» - не есть хорошо, лучше подберите своей переменной другое название, например «args»

jaroslav.tavgen 12.04.2020 13:07

Цитата:

Сообщение от voraa (Сообщение 522678)
В первом правиле говорится про токен-нарушитель. Тоесть нечто такое, что делает синтаксическую конструкцию недопустимой.

Но конструкция }[ - вполне допустима

Array.prototype.sum = function (...arguments){returnthis.reduce(arguments);}[1,2,3]

Мы описали какую то функцию. Функция - это объект. К объекту применима операция [] для получения свойства по имени.
[1,2,3] - тут используется операция ',', которая дает значение последнего из выражений (3)
Т.е приведенный выше пример пытается взять значение свойства с именем '3' у объекта функции. Такого нет, поэтому undefined/

Спасибо большое! Офигеть, конечно. Никогда бы не подумал, что это работает именно так.

Почему все тогда почти никогда не ставят точки с запятой после декларации функций? Эта ситуация настолько редкая? Почти все пишут так:

function foo(){
  return 3;
}

без точки с запятой после закрывающей фигурной скобки.

jaroslav.tavgen 12.04.2020 13:11

Цитата:

Сообщение от Nexus (Сообщение 522679)
jaroslav.tavgen, а что вы, собственно, сделать то пытаетесь?
На имплементацию метода «sum» это не похоже, на алиас базового метода «reduce» - тоже.

Алиас метода reduce.
Цитата:

Сообщение от Nexus (Сообщение 522679)
Хотите понять в чем у вас ошибка - дебажте, посмотрите, что у вас находится в переменной «arguments».

Дебагинг помочь не мог, т.к. до входа внутрь функции дело даже не доходило - сразу сообщение об ошибке про undefined.

Я так понял, что моей ошибкой было то, что вместо того, чтобы рассматривать переданный аргумент как функцию (function(args)) я рассматривал его как массив аргументов (function(...args))

Цитата:

Сообщение от Nexus (Сообщение 522679)
P.S. переопределять значение переменной «arguments» - не есть хорошо, лучше подберите своей переменной другое название, например «args»

Спасибо! Буду иметь в виду.

рони 12.04.2020 13:22

Цитата:

Сообщение от jaroslav.tavgen
я рассматривал его как массив аргументов (function(...args))

и правильно делали в данном случае ...
вопрос на засыпку, как используя только Array.prototype.sum и функцию сложения, получить сумму двух массивов?

voraa 12.04.2020 13:23

Цитата:

Сообщение от jaroslav.tavgen (Сообщение 522683)
Почему все тогда почти никогда не ставят точки с запятой после декларации функций? Эта ситуация настолько редкая?

Редкой бывает ситуация, когда оператор начинается с [ или с (

Например

let a= x + y
(a <4 || 8< a)? x+=10 : x-=10

В этом случае будет попытка вызвать функцию y(a <4 || 8< a)
или
let f = function () {...}
(a <4 || 8< a)? x+=10 : x-=10

То же - определили функцию и сразу пытаемся ее вызвать

SuperZen 12.04.2020 13:23

зачем здесь деструктор?
Array.prototype.sum = function (...arguments)


еще пример:
return true

и
return
true

рони 12.04.2020 13:29

jaroslav.tavgen,
как используя только Array.prototype.sum и функцию сложения, получить сумму двух массивов?
const fn = (a,b)=>a+b;
const a = [1,2,3];
const b = [4,5,6];
Array.prototype.sum = function(...args){ return this.reduce/* ... */};

console.log( /* ... */)//21

voraa 12.04.2020 13:29

Цитата:

Сообщение от рони (Сообщение 522686)
вопрос на засыпку, как используя только Array.prototype.sum и функцию сложения, получить сумму двух массивов?

А функция сложения это что?

рони 12.04.2020 13:37

Цитата:

Сообщение от voraa
А функция сложения это что?

fn = (a,b)=>a+b;
и наверно задание скорее для начинающих.

jaroslav.tavgen 12.04.2020 13:43

Цитата:

Сообщение от рони (Сообщение 522689)
jaroslav.tavgen,
как используя только Array.prototype.sum и функцию сложения, получить сумму двух массивов?
const fn = (a,b)=>a+b;
const a = [1,2,3];
const b = [4,5,6];
Array.prototype.sum = function(...args){ return this.reduce/* ... */};

console.log( /* ... */)//21

const a = [1,2,3];
const b = [4,5,6];
Array.prototype.sum = function(arg){ return [...this, ...arg].reduce((acc,val)=>acc+val, 0)};

console.log(a.sum(b));

если я правильно понял задачу, конечно...

рони 12.04.2020 13:46

Цитата:

Сообщение от jaroslav.tavgen
если я правильно понял задачу

направление правильное, но куда делись строки 1 и 4 из задания?

jaroslav.tavgen 12.04.2020 13:50

Цитата:

Сообщение от рони (Сообщение 522694)
направление правильное, но куда делись строки 1 и 4 из задания?

const fn = (a,b)=>a+b;
const a = [1,2,3];
const b = [4,5,6];
Array.prototype.sum = function(...args){ return this.reduce(fn) + args[0].reduce(fn)};

console.log(a.sum(b))//21

рони 12.04.2020 13:56

jaroslav.tavgen,
а можно без использования знака +(везде) а fn применить только в строке 6 :)

рони 12.04.2020 14:01

jaroslav.tavgen,
хочется сделать более полноценный вариант вашего кода из первого сообщения не слишком изменяя его.

jaroslav.tavgen 12.04.2020 14:22

Цитата:

Сообщение от рони (Сообщение 522696)
jaroslav.tavgen,
а можно без использования знака +(везде) а fn применить только в строке 6 :)

Честно говоря, не понимаю, как без знака + найти сумму, используя reduce. Можно использовать хак с двумя минусами :D ,но явно не это имелось в виду.

рони 12.04.2020 14:25

jaroslav.tavgen,
const fn = (a,b)=>a+b;
const a = [1,2,3];
const b = [4,5,6];
Array.prototype.sum = function(...args){ return this.reduce(...args)};

console.log(a.sum(fn, b.sum(fn)))//21

SuperZen 12.04.2020 14:26

const fn = (a, b) => a + b;
const a = [1, 2, 3];
const b = [4, 5, 6];
Array.prototype.sum = function (...args) {
  return this.reduce(...args);
};
console.log([a, b].map(v => v.sum(fn)).sum(fn, 100));

тоже поучаствую )

рони 12.04.2020 14:34

SuperZen,
:victory:

voraa 12.04.2020 14:42

const fn = (a,b)=>a+b;
const a = [1,2,3];
const b = [4,5,6];
Array.prototype.sum = function(){ return this.reduce(fn)};
 
console.log(fn(a.sum(), b.sum())) //21

рони 12.04.2020 14:59

voraa,
:)

Nexus 12.04.2020 16:31

Вроде такого еще не было:
const fn = (a,b)=>a+b;
const a = [1,2,3];
const b = [4,5,6];
Array.prototype.sum = function() { return this.reduce(...arguments); };
 
console.log([...a, ...b].sum(fn)) //21

Malleys 13.04.2020 04:46

Цитата:

Сообщение от рони
а можно без использования знака +(везде) а fn применить только в строке 6

Если метод называется sum, то он наверное должен сам по себе уметь суммировать...

А то у Nexus (№30), voraa (№28), SuperZen (№26), рони (№25) (см. примеры выше) получается, что если fn заменить на умножение, то метод sum так «просуммирует», что получится умножение... (уже не говоря о сложности использования, которое предполагает дополнительные вызовы fn)

const a = [1, 2, 3];
const b = [4, 5, 6];
Array.prototype.sum = (sum => function(b = []) {
	return b.reduce(sum, this.reduce(sum, 0), 0);
})((a, b) => a + b);
console.log(a.sum(b)) // 21


ЕЩЁ Можно выделить в отдельную функцию...
const reducer = (fn, getInitialValue) => function(b = []) {
    return b.reduce(fn, this.reduce(fn, getInitialValue()), getInitialValue());
};
Array.prototype.sum = reducer((a, b) => a + b, () => 0);
Array.prototype.mul = reducer((a, b) => a * b, () => 1);
Array.prototype.collectOdds = reducer((a, b) => b % 2 === 0 ? a : a.concat(b), () => []);

const a = [1, 2, 3];
const b = [4, 5, 6];

console.log(a.sum(b)) // 21
console.log(a.mul(b)) // 720
console.log(a.collectOdds(b)) // [1, 3, 5]


ЕЩЁ Можно reducer получить при помощи редукции, что позволит передавать в методы более одного массива...
const reducer = (fn, getInitialValue) => function(...as) {
    return [this, ...as].reduce((m, v) => v.reduce(fn, m), getInitialValue());
};
Array.prototype.sum = reducer((a, b) => a + b, () => 0);
Array.prototype.mul = reducer((a, b) => a * b, () => 1);
Array.prototype.collectOdds = reducer((a, b) => b % 2 === 0 ? a : a.concat(b), () => []);

const a = [1, 2, 3];
const b = [4, 5, 6];

console.log([10, 20].sum(a, b)) // 51
console.log(a.mul(b)) // 720
console.log([-1].collectOdds(a, b)) // [-1, 1, 3, 5]

рони 13.04.2020 08:05

Malleys,
:write:

Nexus 13.04.2020 11:48

Цитата:

Сообщение от Malleys
Если метод называется sum, то он наверное должен сам по себе уметь суммировать.

Со слов автора, он хотел написать только алиас метода reduce.
Почему для алиаса он использовал название "sum" - непонятно.


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