javascript - 声明为常量的数组仍在 javascript 中进行操作
问题描述
所以我在 javascript 和 HTML5 Canvas 中构建了一个圆形随机颜色选择器实用程序,所有组件都是动态的,对象的大小会根据屏幕大小进行调整,并且间距也会根据屏幕大小进行调整。此外,如果用户调整显示大小,该实用程序也会动态调整大小。
我正在使用一个数组来存储圆圈的颜色。生成圆圈时,它们使用数组中的第一种颜色,从数组中删除该颜色,然后对数组进行洗牌。
问题是当用户调整显示大小时,颜色数组没有足够的颜色来绘制所有的圆圈,这是因为代码删除了使用的颜色,因此没有重复。但是,我尝试通过声明一个名为origColours的颜色常量数组并将颜色数组设置为等于 origColours 数组来解决此问题。
下面是我写的代码。我看不到origColours数组被操纵的方式或原因,希望您能提供帮助
:)
//########//SETUP
var canvas = document.getElementById("myCanvas");
var c = canvas.getContext("2d");
canvas.height = innerHeight;
canvas.width = innerWidth;
document.documentElement.style.overflow = 'hidden'; // firefox, chrome
document.body.scroll = "no"; // ie only
//########//COLORS
const origColours = ["#1c2133", "#2b6ea8", "#5d99bf", "#333968", "#000000", "#b000b0", "#0000aa", "#ff0000", "#00aaaa", "#7CFC00", "#00FF7F", "#8B0000", "#F0E68C"];
var colours = ["#1c2133", "#2b6ea8", "#5d99bf", "#333968", "#000000", "#b000b0", "#0000aa", "#ff0000", "#00aaaa", "#7CFC00", "#00FF7F", "#8B0000", "#F0E68C"];
//########//VARIABLES
var backgroundColour = 0;
var mouse = {
x: undefined,
y: undefined,
};
var key = {
keyCode: undefined,
}
var mainRadius = 0;
var smallRadius = 0;
var pointerCircle;
var circles = [];
//########//EVENTS
window.addEventListener("mousemove", function(event) {
mouse.x = event.x;
mouse.y = event.y;
})
window.addEventListener("keypress", function(event) {
key.keyCode = event.keyCode;
if (key.keyCode == 32) {
switchBg();
}
})
window.addEventListener('resize', function(event) {
canvas.width = innerWidth
canvas.height = innerHeight
setup();
})
//########//OBJECTS
function Circle(x, y, radius, colour) {
this.x = x;
this.y = y;
this.radius = radius;
//this.n = Math.floor(Math.random()*colours.length);
if (colour == undefined) {
//this.fill = colours[this.n];
this.fill = colours[0];
this.orignalFill = this.fill;
colours.shift();
colours = shuffleArray(colours);
} else {
this.fill = colour;
this.orignalFill = this.fill;
}
this.draw = function() {
c.fillStyle = this.fill;
c.strokeStyle = this.colour;
c.beginPath();
c.arc(this.x,this.y,this.radius,0,Math.PI*2);
c.fill();
}
this.update = function() {
//Bounce off the edges
// if (this.x + this.radius > innerWidth || this.x - this.radius < 0) {
// this.dx = -this.dx;
// }
// if (this.y + this.radius > innerHeight || this.y - this.radius < 0) {
// this.dy = -this.dy;
// }
//Move circle
// this.x += this.dx;
// this.y += this.dy;
//Draw the circle after all calculations have been made
this.draw();
}
}
//########//UTILITY FUNCTIONS
function shuffleArray(arr) {
var j, x, i;
for (i = arr.length - 1; i > 0; i--) {
j = Math.floor(Math.random() * (i + 1));
x = arr[i];
arr[i] = arr[j];
arr[j] = x;
}
return arr;
}
function checkCollisions(obj1, objs) {
for (var i = 0; i < objs.length; i++) {
if (checkCollision(obj1, objs[i])) {
return objs[i]
}
}
}
function renderCircles(arr) {
for (var i = 0; i < arr.length; i++) {
arr[i].update();
}
}
function checkCollision(object1, object2) {
var obj_s = getDistance(object1.x, object1.y, object2.x, object2.y);
if (obj_s < object1.radius + object2.radius) {
return true;
} else {
return false;
}
}
function getDistance(x1, y1, x2, y2) {
xs = x2 - x1;
ys = y2 - y1;
return Math.sqrt(Math.pow(xs, 2) + Math.pow(ys, 2));
}
function switchBg() {
if (backgroundColour == 0) {
document.body.style.backgroundColor = "black"
backgroundColour = 1
} else if (backgroundColour == 1) {
document.body.style.backgroundColor = "white"
backgroundColour = 0
}
}
//########//ANIMATION
function animate() {
requestAnimationFrame(animate);
c.clearRect(0,0,innerWidth,innerHeight);
pointerCircle.x = mouse.x;
pointerCircle.y = mouse.y;
var result = checkCollisions(pointerCircle, circles);
if (result != undefined) {
circles[0].fill = result.fill;
} else {
circles[0].fill = circles[0].orignalFill;
}
pointerCircle.update();
renderCircles(circles);
}
//########//RUNNING CODE
function setup() {
if (innerHeight >= innerWidth) {
mainRadius = innerWidth/6;
} else {
mainRadius = innerHeight/6;
}
smallRadius = mainRadius/2;
c.clearRect(0,0,innerWidth,innerHeight);
circles = [];
colours = origColours
pointerCircle = new Circle(0,0,1, "rgba(0,0,0,0)");
circles.push(new Circle(innerWidth/2, innerHeight/2, mainRadius, "white"));
circles.push(new Circle((innerWidth/2)-mainRadius*2, innerHeight/2, smallRadius));
circles.push(new Circle((innerWidth/2)+mainRadius*2, innerHeight/2, smallRadius));
circles.push(new Circle((innerWidth/2), (innerHeight/2)-mainRadius*2, smallRadius));
circles.push(new Circle((innerWidth/2), (innerHeight/2)+mainRadius*2, smallRadius));
var angCoE = mainRadius / 2 * 3;
circles.push(new Circle((innerWidth/2)+angCoE, (innerHeight/2)-angCoE, smallRadius));
circles.push(new Circle((innerWidth/2)+angCoE, (innerHeight/2)+angCoE, smallRadius));
circles.push(new Circle((innerWidth/2)-angCoE, (innerHeight/2)-angCoE, smallRadius));
circles.push(new Circle((innerWidth/2)-angCoE, (innerHeight/2)+angCoE, smallRadius));
}
setup();
animate();
解决方案
注意:所以我有点太仓促了,没有仔细阅读你的问题。真正的解决方案是由 Hey24sheep 和 pooyan 下面发布的——我把这个留在这里是为了解释这个问题的不同方面。
将变量声明为const
意味着您无法更改其值。如果有问题的变量包含对对象(例如数组)的引用,这意味着您不能使变量引用不同的对象。
例如,如果您尝试这样做:
const colors = [ 'red', 'green', 'blue' ];
colors = [ 'yellow', 'cyan', 'magenta' ];
这将失败,因为您正在尝试更改colors
所指的内容。但是,数组本身是一个独立于变量的实体,它的属性仍然可以自由操作。
在这种情况下,您要寻找的是Object.freeze()
:
const colors = Object.freeze([ 'red', 'green', 'blue' ]);
现在您会发现您无法添加、删除或更改数组的任何元素。而且,由于您使用 对其进行了处理const
,因此您也无法重新分配该变量colors
。
更多信息:
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/freeze
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/const
推荐阅读
- java - 为什么Java在macOS上使用绝对路径返回不同的“文件存在”结果取决于它是否是从脚本调用的?
- amazon-web-services - 将 Lambda 连接到 Redis 集群,无需在 lambda 环境中对 Redis 主机/端口进行硬编码,因为这两个资源都是在同一个 CDK 堆栈中创建的
- java - 尽管实际和预期相同,但 RESULT 对象的 Junit 断言错误
- python - 单元格颜色excel数据框熊猫
- sandbox - 我可以使用 Golang/Python 构建自己的沙盒环境吗?
- reactjs - 在 useform 结果中提交获取的数据会触发错误
- z-index - 在 react-native-maps 中的街道名称上绘制折线
- python - 在虚拟环境中导入python中的numpy和scipy库
- android - 当我用颤振向 asp.net core(local) 发送请求时,我收到 (Connection reset by peer) 错误
- oauth-2.0 - oAuth 令牌会被盗吗