为什么改变一个参数的副本变化的说法? [英] Why does changing a copy of an argument change the argument?

查看:134
本文介绍了为什么改变一个参数的副本变化的说法?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个函数,以产生给定的若干瓦片,起始地图,和网格(三角形,正方形,十六进制)的类型使用随机地图。它返回瓷砖的数组,地图,有两个额外的属性:种子,启动地图应用,而 adjy *。最初,地图设置为等于种子。出于某种原因, map.seed 不等于种子参数。相反, map.seed 等于地图。我想通了,种子改变map.push()。我曾尝试使用严格; ,使用参数[1] 而不是种子,动人的语句 map.seed =种子; 左右(这些没有任何效果)。在code没有在jsHint任何错误,并在控制台不会引发任何

I have a function to generate a random map given a number of tiles, a starting map, and the type of grid (triangular,square,hex) to use. It returns an array of tiles, map, with two extra properties: seed, the starting map used, and adjy*. Initially, map is set to equal seed. For some reason, map.seed does not equal the seed argument. Instead, map.seed equals map. I figured out that seed is changed by map.push(). I have tried "use strict";, using arguments[1] instead of seed, and moving the statement map.seed=seed; around (these didn't have any effect). The code doesn't have any errors in jsHint and doesn't throw any in the console.

* adjy 是短期的邻接,是六边形0三角形,1广场,2

*adjy is short for adjacency, and is 0 for triangles, 1 for squares, and 2 for hexagons.

我有prepared一个的jsfiddle 和code也是如下:

I have prepared a jsFiddle and the code is also below:

console.clear();
var canvas=document.getElementById('canvas'),
    ctx=canvas.getContext('2d');
canvas.width=window.innerWidth;
canvas.height=window.innerHeight;
ctx.translate(canvas.width/2,canvas.height/2);
Array.prototype.equals=function(a){//array1==array2 is broken, create substitute
    return this.length==a.length&&this.every(
        function(e,i){
            return e instanceof Array?
                a[i]instanceof Array&&e.equals(a[i]):
                !(a[i]instanceof Array)&&e==a[i];
        }
    );
};
Array.prototype.includes=function(n){
    return this.some(
        function(e){
            return n instanceof Array?
                n.equals(e):
                n==e;
        }
    );
};
function Map(tiles,seed,adjy){
    if(!arguments.length)return [];
    if(arguments.length<2)
        if(tiles)seed=[[0,0]];
        else return [];
    if(arguments.length<3)
        if(tiles<seed.length)return adjy;//returns undefined
        else adjy=1;
    var map=seed,cdd=[],nos=//candidate tiles,Neighbors Of Square (or tile)
        [[[0,1,-1],[1,0,0]],//triangle
         [[0,1,0,-1],[1,0,-1,0]],//square
         [[0,1,1,0,-1,-1],[1,0,-1,-1,0,1]]][adjy];//hex
    function addAdj(p){//adds adjacent tiles to candidates (cdd)
        var c;
        for(var i=0;i<nos[0].length;i++)
            if(!cdd.includes(
               c=[p[0]+nos[0][i],p[1]+nos[1][i]])&&
               !map.includes(c))
                  cdd.push(c);
    }
    function pickR(){//pick a random tile
        var p=cdd.splice(
            ~~(Math.random()*cdd.length),1)[0];//~~ is the same as floor
        addAdj(p);
        map.push(p);//the line where the problem happens
    }
    seed.forEach(addAdj);
    while(tiles>map.length)pickR();
    map.seed=seed;
    map.adjy=adjy;
    return map;
}
function drawMap(map){
    if(!map.hasOwnProperty('adjy'))return void 0;
    function draw0(c){
        var x=c[0],y=c[1];
        ctx.beginPath();
        switch((x+y)%2){
            case 0:
                x*=5;y*=7;
                ctx.moveTo(x,y);
                ctx.lineTo(x-5,y+7);
                ctx.lineTo(x+5,y+7);
                break;
            default:
                x*=5;y*=7;
                ctx.moveTo(x,y+7);
                ctx.lineTo(x+5,y);
                ctx.lineTo(x-5,y);
        }
        ctx.closePath();
        ctx.fill();
    }
    function draw1(c){
        var x=c[0],y=c[1];
        ctx.fillRect(x*10,y*10,10,10);
    }
    function draw2(c){
        var x=c[0]*7,y=c[1];
        x+=y*3.5;
        y*=7.5;
        ctx.beginPath();
        ctx.moveTo(x,y);
        ctx.lineTo(x,y+5);
        ctx.lineTo(x+3.5,y+7.5);
        ctx.lineTo(x+7,y+5);
        ctx.lineTo(x+7,y);
        ctx.lineTo(x+3.5,y-2.5);
        ctx.closePath();
        ctx.fill();
    }
    switch(map.adjy){
        case 0:
            map.forEach(draw0);
            break;
        case 1:
            map.forEach(draw1);
            break;
        default:
            map.forEach(draw2);
    }
}
var board=new Map(37*6,[[-5,0],[5,0]],2);
console.log(board.seed);
drawMap(board);

我已经包括了所有的情况下,在code的问题不是事实,种子更新时地图是,虽然我的开发者控制台测试表明这一点。

I have included all of the code in case the problem is not in fact that seed is updated when map is, though my developer console tests suggest this.

推荐答案

指定数组或对象做的的做它的一个副本。

Assigning an array or object does not make a copy of it.

var map = seed;

使两个变量引用的相同的数组。其结果是,可以使经由一个变量阵列的任何变化将通过其他看到。如果你想要一个副本,你必须明确地做到这一点:

makes the two variables reference the same array. As a result, any changes you make to the array via one variable will be seen through the other. If you want a copy, you have to do it explicitly:

var map = seed.slice(0);

这篇关于为什么改变一个参数的副本变化的说法?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆