Как мне передать динамическую переменную в функцию javascripts .forEach()?

#javascript #variables #dynamic #foreach

#javascript #переменные #динамический #foreach

Вопрос:

Как мне передать динамическую переменную image[i] в .Функция forEach()?
Я получаю эту ошибку, когда пытаюсь использовать свою переменную: Uncaught SyntaxError: Invalid destructuring assignment target

 images.forEach((image[i]) => {
  if(iter == 0){ ctx.drawImage(image[i], 60, 270);}
  if(iter == 1){ ctx.drawImage(image[i], 80, 270);}
  if(iter == 2){ ctx.drawImage(image[i], 100, 270);}
  console.log(iter);
});  
  

Редактировать:

Вот вся функция

     // Account UI
    function accountUI(str) {
        // Parse MOTD for use
        var motd = str.match( /<motd>[^<>]*?</motd>/igm );

        // Clean un-needed spaces amp; tags
        var motd_clean = motd[0];
        motd_clean = motd_clean.replace("<motd>", "");
        motd_clean = motd_clean.replace("</motd>", "");
        motd_clean = motd_clean.replace(/[r] /g, '');
        motd_clean = $.trim(motd_clean);

        // Create textarea for MOTD
        $("#can_wrapper").append('<textarea id="motd" name="motd" disabled>'   motd_clean   '</textarea>');

        // Create blue background for players
        ctx.fillStyle = "#333399";
        ctx.fillRect(2, 255, 596, 181);

        // Parse player names for use
        var players = str.match( /<players>([sS]*?)</players>/m );
        var players = players[0];
        var item = str.match( /<item([sS]*?)>/mg );

        // For every player run iteration
        var image = [];
        for (var i = 0; i < item.length;   i) {
            // Position for players on account screen
            if(i == 0){ var pos = "61px";var iter = 0;}
            if(i == 1){ var pos = "168px";var iter = 1;}
            if(i == 2){ var pos = "275px";var iter = 2;}
            console.log(i);
            console.log("1 -> "   iter);
            // Gets player name from string
            var player = item[i].match( /([A-Z])w /g );

            // Create player div for mouse interaction
            var player_el = $('<div class="cursor player" id="player'  player  '"></div>');
            $("#can_wrapper").append(player_el);
            $("#player"  player).css({"position": "absolute", "height": "50px", "width": "50px", "left": ""  pos  "", "top": "271px", "cursor": "grab", "cursor": "-webkit-grab"});

            // Get player name for hover action
            var player_name_el = player;
            document.styleSheets[0].addRule('#player'  player  ':hover::after','content: "' player_name_el '";');

            /**
             * Promisify loading an image
             * @param {String} imagePath The web location of the image
             * @returns {Promise} A Promise that will resolve to an Image
             */
            function loadImage(imagePath) {
                return new Promise((resolve, reject) => {
                    image[i] = new Image();
                    image[i].addEventListener("load", () => {
                        resolve(image[i]);
                    });
                    image[i].addEventListener("error", (err) => {
                        reject(err);
                    });
                    image[i].src = 'https://www.example.com/interface/images/body/'   imagePath;
                });
            }

            var imageSources = ['v1456.png', 'vbody0.png','vhead14.png','v1960.png','v578.png','v1221.png', 'v3063.png']; // url and order

            Promise
                .all(imageSources.map(ii => loadImage(ii)))
                .then((images) => {
                    images.forEach((image[i]) => {
                        if(iter == 0){ ctx.drawImage(image[i], 60, 270);}
                        if(iter == 1){ ctx.drawImage(image[i], 80, 270);}
                        if(iter == 2){ ctx.drawImage(image[i], 100, 270);}
                        console.log(iter);
                    });
                }).catch((err) => {
                    console.error(err);
                });

        }
    }
  

Комментарии:

1. Посмотрите на документацию , вам не нужна [i] , поскольку первым параметром является текущее значение

Ответ №1:

Переменная перед => — это имя, которое вы присваиваете каждому элементу массива, над которым вы forEach работаете в цикле. Вам не нужно использовать [] обозначения, просто имя:

 images.forEach((image) => {
  if(iter == 0){ ctx.drawImage(image, 60, 270);}
  if(iter == 1){ ctx.drawImage(image, 80, 270);}
  if(iter == 2){ ctx.drawImage(image, 100, 270);}
  console.log(iter);
});
  

Комментарии:

1. Также похоже, что iter — это итерация, которая atm, похоже, находится вне цикла. Однако forEach позволяет передавать второй параметр, который является индексом, как показано в документах

Ответ №2:

Вам не нужно создавать глобальный массив изображений, попробуйте следующий код

Вы также можете использовать Promise.map

 // Account UI
function accountUI(str) {
	// Parse MOTD for use
	var motd = str.match(/<motd>[^<>]*?</motd>/igm);

	// Clean un-needed spaces amp; tags
	var motd_clean = motd[0];
	motd_clean = motd_clean.replace("<motd>", "");
	motd_clean = motd_clean.replace("</motd>", "");
	motd_clean = motd_clean.replace(/[r] /g, '');
	motd_clean = $.trim(motd_clean);

	// Create textarea for MOTD
	$("#can_wrapper").append('<textarea id="motd" name="motd" disabled>'   motd_clean   '</textarea>');

	// Create blue background for players
	ctx.fillStyle = "#333399";
	ctx.fillRect(2, 255, 596, 181);

	// Parse player names for use
	var players = str.match(/<players>([sS]*?)</players>/m);
	var players = players[0];
	var item = str.match(/<item([sS]*?)>/mg);

	// For every player run iteration
	
	for (var i = 0; i < item.length;   i) {
		// Position for players on account screen
		if (i == 0) { var pos = "61px"; var iter = 0; }
		if (i == 1) { var pos = "168px"; var iter = 1; }
		if (i == 2) { var pos = "275px"; var iter = 2; }
		console.log(i);
		console.log("1 -> "   iter);
		// Gets player name from string
		var player = item[i].match(/([A-Z])w /g);

		// Create player div for mouse interaction
		var player_el = $('<div class="cursor player" id="player'   player   '"></div>');
		$("#can_wrapper").append(player_el);
		$("#player"   player).css({ "position": "absolute", "height": "50px", "width": "50px", "left": ""   pos   "", "top": "271px", "cursor": "grab", "cursor": "-webkit-grab" });

		// Get player name for hover action
		var player_name_el = player;
		document.styleSheets[0].addRule('#player'   player   ':hover::after', 'content: "'   player_name_el   '";');

		/**
		 * Promisify loading an image
		 * @param {String} imagePath The web location of the image
		 * @returns {Promise} A Promise that will resolve to an Image
		 */
		function loadImage(imagePath) {
			return new Promise((resolve, reject) => {
				let image = new Image();
				imag.addEventListener("load", () => {
					resolve(image);
				});
				image.addEventListener("error", (err) => {
					reject(err);
				});
				image.src = 'https://www.example.com/interface/images/body/'   imagePath;
			});
		}

		var imageSources = ['v1456.png', 'vbody0.png', 'vhead14.png', 'v1960.png', 'v578.png', 'v1221.png', 'v3063.png']; // url and order

		Promise.all(imageSources.map(ii => loadImage(ii))).then((images) => {
			images.forEach((image) => {
				if (iter == 0) { ctx.drawImage(image, 60, 270); }
				if (iter == 1) { ctx.drawImage(image, 80, 270); }
				if (iter == 2) { ctx.drawImage(image, 100, 270); }
				console.log(iter);
			});
		}).catch((err) => {
			console.error(err);
		});

	}
}  

Комментарии:

1. Это дает мне: index.html:419 TypeError: Cannot read property '0' of undefined для images[i] в 3 ctx.drawImage(images[i], 60, 270

2. только что просмотрел ваш обновленный вопрос, вам нужно только изображение, на которое уже дан ответ.

3. Спасибо за помощь. Я предполагаю, что она рисует изображение так, как должно, это показывает, что на 3-й итерации было нарисовано 21 изображение. Это означает, что мои if (iter == 1) не работают, и все зависит от последней.

4. измените все переменные на let специально в первом цикле for

Ответ №3:

Вы могли бы переместить параметры в массив и вызвать значения с индексом.

 images.forEach(image => ctx.drawImage((image[i], [60, 80, 100][iter], 270)):
  

Комментарии:

1. Я получаю эту ошибку: index.html:414 TypeError: Failed to execute 'drawImage' on 'CanvasRenderingContext2D': The provided value is not of type я предполагаю, потому что она все еще ожидает image[i]

2. откуда i берется?

3. Строка 27 в обновленной части моего вопроса. for (var i = 0; i < item.length; i) {