#javascript #html5-canvas
Вопрос:
Рассмотрим следующую функцию, которая должна рисовать изображение на холсте по частям, кэшировать эти фрагменты, а затем в следующем цикле проверять эти кэшированные фрагменты, чтобы убедиться, что мы ничего не рисуем больше одного раза. Если консоль.журнал подтверждает, что кэшированный массив чанков никогда не очищается, почему при pixels.data == cachedImage[y][x]
печати результата он всегда возвращается false
, но после обновления кэша он сообщает как true
?
async function temp() {
const DIVIDE = 8;
for(let y = 0; y < DIVIDE; y ) {
if(cachedImage[y] == undefined) {cachedImage[y] = []; console.log(y);}
for(let x = 0; x < DIVIDE; x ) {
let widthChunk = (drawBuffer.width)/DIVIDE;
let heightChunk = (drawBuffer.height)/DIVIDE;
let pixels = ctx.getImageData(x*widthChunk,y*heightChunk,widthChunk-1,heightChunk-1);
let pixeldata = pixels.data;
debugBox3.innerHTML = (cachedImage[y][x] == pixels.data); // always "false"
if(pixels.data == cachedImage[y][x]) {
} else {
cachedImage[y][x] = pixels.data;
ctxFinal.putImageData(pixels,x*widthChunk,y*heightChunk)
}
debugBox4.innerHTML = (cachedImage[y][x] == pixels.data); // always "true"
}
}
}
await temp();
Комментарии:
1. Вы спрашиваете, почему
cachedImage[y][x] == pixels.data
значение true сразу после установкиcachedImage[y][x] = pixels.data;
???2. Я спрашиваю, почему, когда цикл повторяется,
cachedImage[y][x] == pixels.data
внезапно становится false .3. Потому что это новое местоположение в массиве? Это не
data
массив, поэтому ваше сравнение должно измениться.4. Этого не должно быть, старое местоположение должно быть заменено.
5. Массивы являются объектами — поэтому
ImageData.data
возвращает ссылку на объект массива. Вы не можете проверить эквивалентность объектов с помощью простых операторов эквивалентности (===
).
Ответ №1:
Предположим, что следующий код:
let object1 = { key: 'value' }
var object2 = { key: 'value' }
Можно было бы подумать, что object1 == object2
это правда, но это не так. Почему? Потому что object1 и object2 являются просто ссылками на объекты — то есть на независимые объекты.
Однако, если мы расширим код:
let object1 = { key: 'value' }
var object2 = { key: 'value' }
object1 = object2
Теперь мы установили переменную object1 равной ссылке на object2. Мы не скопировали object2 .
Следовательно object1 == object2
, теперь true .
Когда вы говорите cachedImage[y][x] = pixels.data;
, что на самом деле cachedImage[y][x]
ссылаетесь на pixels.data
. Только тогда оно равно пикселям.данные (которые также являются просто ссылкой).
Это несколько знакомо с указателями в c, см.: https://www.sitepoint.com/how-javascript-references-work .
Комментарии:
1. Итак, как бы мне установить содержимое
cachedImage[y][x]
в значениеpixels.data
?2. используйте Object.is (obj1, obj2) вместо obj1===obj2
3. если бы вы действительно хотели, вы могли бы сказать cachedImage[y][x] = { … пиксели. данные } (если пиксели. данные — это объект, иначе используйте […пикселей. данные ]) но это было бы ужасно неэффективно по соображениям памяти