Javascript-форум (https://javascript.ru/forum/)
-   Общие вопросы Javascript (https://javascript.ru/forum/misc/)
-   -   Миллион нубских вопросов от новичка (https://javascript.ru/forum/misc/77076-million-nubskikh-voprosov-ot-novichka.html)

MarkSM 22.03.2019 03:15

Миллион нубских вопросов от новичка
 
И так уже в который раз пытаюсь выучить JS никак не получаеться и не хватает силы воли. В этот раз надеюсь смогу добиться успеха.

В этой теме хотел бы задавать просто все вопросы которые меня мучают и какими бы они тупыми не казались хотелось бы увидеть на них ответы)


Почему в данных двух функциях, есть доступ к переменной let array из function sum если как я читал в книге особенностью переменных let как раз является их действенность только внутри скобок которых она находиться, в моей случае внутри function range.

function range (start, end) {
let array = [];
for (var i = 1; i <= 10; i++) {
array.push(i);
}

return array;
}

function sum(array) {
let total = 0;
for (let value of array) {
total += value;
}

return total;
}

laimas 22.03.2019 03:21

Цитата:

Сообщение от MarkSM
есть доступ к переменной let array из function sum

Нет такого доступа.

MarkSM 22.03.2019 03:23

Спасибо за ответ! Но для понимания я бы хотел услышать уточнение разве из function sum не происходит обращение к этой переменной?

laimas 22.03.2019 03:31

Цитата:

Сообщение от MarkSM
разве из function sum не происходит обращение к этой переменной

Где вы это видите? Потому что это же имя? Ну так в функции sum это аргумент функции, а не то что в какой-то иной было объявлено. С таким же успехом аргумент можно было бы обозвать как "asdf", какая разница, вот только по смыслу такое имя не годится.

var a = range (0, 10); //чему будет равна a и является ли она непосредственно переменной array функции?
a = sum(a); //чему будет равна a?

MarkSM 22.03.2019 03:41

[quote=laimas;505145]Где вы это видите? Потому что это же имя? Ну так в функции sum это аргумент функции, а не то что в какой-то иной было объявлено. С таким же успехом аргумент можно было бы обозвать как "asdf", какая разница, вот только по смыслу такое имя не годится.

Спасибо теперь я понял что это лишь имя аргумента!:agree:

рони 22.03.2019 08:19

MarkSM,
Пожалуйста, отформатируйте свой код!

Для этого его можно заключить в специальные теги: js/css/html и т.п., например:
[html run]
... минимальный код страницы с вашей проблемой
[/html]

О том, как вставить в сообщение исполняемый javascript и html-код, а также о дополнительных возможностях форматирования - читайте http://javascript.ru/formatting.

Malleys 22.03.2019 11:02

Тоже самое можно написать так, и тогда такого вопроса не возникает!

function* range(start, end) {
	for (let i = start; i <= end; i++)
		yield i;
}

function sum(array) {
	let total = 0;
	for(const value of array)
		total += value;

	return total;
}

// range(0, 10) |> sum |> alert;
alert(sum(range(0, 10)));

Nexus 22.03.2019 13:17

Malleys, в чем преимущество генератора над обычным массивом в коде из поста №7?

Malleys 22.03.2019 13:34

Код в первом посте range(0, 10) создаёт массив чисел, а затем, при суммировании, на нём (на массиве) запускается итератор массива.

В №7 range(0, 10) создаёт итератор, который запускается при суммировании.

Ещё пример, добавлю функцию
function* take(n, xs) {
	for(const x of xs) {
		if(n-- <= 0)
			break;

		yield x;
	}
}


Теперь, если использовать определения из №1, то alert(sum(take(5, range(1, Infinity)))); никогда ничего не вернёт, поскольку сначала попытается создать массив из всех натуральных чисел! (я в курсе про Number.MAX_SAFE_INTEGER)

Теперь, если использовать определения из №7, то alert(sum(take(5, range(1, Infinity)))); результат будет, поскольку оно просуммирует столько чисел, сколько указано!

Nexus 22.03.2019 13:54

Malleys, я знаю, как ведут себя генераторы.
Интересовало почему вы в 7-м посте генератор использовали, результат-то, по сути, один и тот же.
Без генератора скрипт будет пытаться создать массив бесконечной длины, с генератором будет суммировать числа до бесконечности.

MarkSM 22.03.2019 18:57

Зачем в данном случае нужен метод Math.floor, если убрав его ничего не меняется. Буду благодарен за ответ , для моего понимания...


function reverseArrayInPlace(array) {
for (var i = 0; i < Math.floor(array.length - 1 - i); i++) {
let old = array[i];
array[i] = array[array.length - 1 - i];
array[array.length - 1 - i] = old;
}
return array;
}




let arrayValue = [1, 2, 3, 4, 5, 6];
reverseArrayInPlace(arrayValue);
console.log(arrayValue);
// → [6, 5, 4, 3, 2, 1]

j0hnik 22.03.2019 19:02

В данном случае Math.floor не нужен

function reverse(array) {
	var j = array.length - 1;
	for (var i = 0; i < j; i++, j--) {
		[array[i], array[j]] = [array[j], array[i]];
	}
	return array;
}

Malleys 25.03.2019 09:18

Цитата:

Сообщение от Nexus
Без генератора скрипт будет пытаться создать массив бесконечной длины, с генератором будет суммировать числа до бесконечности.

Nexus, пробовать надо хотя бы, уверенность без экспериментов пустые слова и буквы и слова...

Nexus 25.03.2019 09:30

Цитата:

Сообщение от Malleys
Nexus, пробовать надо хотя бы, уверенность без экспериментов пустые слова и буквы и слова...

Попробовал, разницы с тем, что я написал не увидел.

//Attention: infinity loop
function* range(start, end) {
	for (let i = start; i <= end; i++)
		yield i;
}

function sum(array) {
	let total = 0;
	for(const value of array)
		total += value;

	return total;
}

sum(range(0, Infinity));

Malleys 25.03.2019 09:48

ОК, я такого, что вы тут написали даже и не запускал! В №9 чуть другой пример!

Вычисление range(1, Infinity) |> take.bind(null, 5) |> sum |> alert без итератора (Осторожность! Бесконечный цикл!)
function range(start, end) {
	let array = []; 
	for (var i = start; i <= end; i++)
		array.push(i);

	return array;
} 

function sum(array) {
	let total = 0;
	for(const value of array)
		total += value;

	return total;
}

function* take(n, xs) {
	for(const x of xs) {
		if(n-- <= 0)
			break;

		yield x;
	}
}

alert(sum(take(5, range(1, Infinity))));


Вычисление range(1, Infinity) |> take.bind(null, 5) |> sum |> alert с итератором (Запускайте смело!)
function* range(start, end) {
	for (let i = start; i <= end; i++)
		yield i;
}

function sum(array) {
	let total = 0;
	for(const value of array)
		total += value;

	return total;
}

function* take(n, xs) {
	for(const x of xs) {
		if(n-- <= 0)
			break;

		yield x;
	}
}

alert(sum(take(5, range(1, Infinity))));

Nexus 25.03.2019 09:52

Цитата:

Сообщение от Malleys
В №9 чуть другой пример!

Я не про этот пример, с ним-то все понятно)
Меня изначально интересовало почему вы в коде из поста №7 использовали генератор, причина этого. Может я чего-то не знаю.
Видимо причины особой использовать генератор не было.
Не буду вас больше мучить вопросами, спасибо.

Malleys 25.03.2019 11:07

Цитата:

Сообщение от Nexus
Меня изначально интересовало почему вы в коде из поста №7 использовали генератор, причина этого.

Так я же ответил в посте №9. Первые два предложения отвечают на ваш вопрос, вы видимо не поняли что это значит, поэтому сначала откройте Chrome DevTools (⌥⌘I), затем запустите примеры в этом посте и посмотрите, как они выполняются по шагам, для этого в панели Sources нажимайте последовательно на Step into next function call , чтобы последовательно пройти через выполнение кода.

Вычисление range(1, Infinity) |> sum |> alert без итератора
function range(start, end) {
	let array = []; 
	for (var i = start; i <= end; i++)
		array.push(i);

	return array;
} 

function sum(array) {
	let total = 0;
	for(const value of array)
		total += value;

	return total;
}

debugger;
alert(sum(range(1, 5)));


Вычисление range(1, Infinity) |> sum |> alert с итератором
function* range(start, end) {
	for (let i = start; i <= end; i++)
		yield i;
}

function sum(array) {
	let total = 0;
	for(const value of array)
		total += value;

	return total;
}

debugger;
alert(sum(range(1, 5)));

рони 25.03.2019 11:21

Цитата:

Сообщение от Malleys
сначала откройте Chrome DevTools (⌥⌘I), затем запустите примеры в этом посте и посмотрите, как они выполняются по шагам, для этого в панели Sources нажимайте последовательно на Step into next function call

:thanks:

Nexus 25.03.2019 11:29

Цитата:

Сообщение от Malleys
Так я же ответил в посте №9. Первые два предложения отвечают на ваш вопрос, вы видимо не поняли что это значит

Все там понятно.
Непонятно, чем хуже вариант, в котором сначала создается массив значений, а после его значения суммируются.

Malleys 25.03.2019 11:34

Цитата:

Сообщение от Nexus
Непонятно, чем хуже вариант, в котором сначала создается массив значений, а после его значения суммируются.

Я нигде не говорил, что он хуже. В общем и целом сложность предложенного алгоритма была O(2n), я предложил вариант с O(n). Это не так критично, если вы только не будете суммировать миллионы чисел.

laimas 25.03.2019 11:54

Цитата:

Сообщение от Nexus
Непонятно, чем хуже вариант, в котором сначала создается массив значений

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

Nexus 25.03.2019 12:14

Malleys, спасибо.

Nexus 25.03.2019 12:18

laimas, задача, в которой требуется создать огромный массив по определенному правилу и дальше произвести над ним какие-то манипуляции, имхо, очень специфична.
Если и нужно будет работать с таким массивом, то он, скорее всего, уже будет создан, уже находится в памяти.
Однако спасибо.

laimas 25.03.2019 12:29

Цитата:

Сообщение от Nexus
имхо, очень специфична

Ну насколько я могу судить уже по функции, об этом как раз и речь. :)

Nexus, вы же и РНР знаете, и если в JS генераторы в общем то, можно сказать, это новинка, то в РНР эта штуковина существует с версии 5.5, а это десяток лет.

Тоже самое что и в JS по сути, только без всякого тумана со звездочками. :)

Nexus 25.03.2019 12:50

laimas,
Цитата:

Сообщение от laimas
Nexus, вы же и РНР знаете, и если в JS генераторы в общем то, можно сказать, это новинка, то в РНР эта штуковина существует с версии 5.5, а это десяток лет.

С генераторами знаком.

Было интересно почему Malleys решил использовать генератор.
Так как он обладает куда бОльшими знаниями, нежели я, решил узнать причину использования генератора.
Может быть открыл бы для себя что новое)

MarkSM 26.03.2019 19:27

J0hnik

Попробовал запустисть ваш код, ответ не выводиться в обратном порядке. Я что-то делаю не так? Или ошибка в коде?

function reverseArrayInPlace2(array) {
	var j = array.length - 1;
	for (var i = 0; i < j; i++, j--) {
		[array[i], array[j]] = [array[j], array[i]];
	}
	return array;
}


reverseArrayInPlace2(arrayValue);
let arrayValue = [1, 2, 3, 4, 5, 6];
console.log(arrayValue);

рони 26.03.2019 19:47

MarkSM,

Пожалуйста, отформатируйте свой код!

Для этого его можно заключить в специальные теги: js/css/html и т.п., например:
[html run]
... минимальный код страницы с вашей проблемой
[/html]

О том, как вставить в сообщение исполняемый javascript и html-код, а также о дополнительных возможностях форматирования - читайте http://javascript.ru/formatting.

рони 26.03.2019 19:52

Цитата:

Сообщение от MarkSM
Я что-то делаю не так?

сначала создание массива, потом преобразование, строки n и n+1 поменяйте местами.


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