javascript Slice没有做浅拷贝

时间:2018-03-15 01:10:44

标签: javascript

我在JS程序之后编写了这个来解决N-queen问题并且工作正常。 但后来我试图用特定格式修改输出。 然后我发现了一个奇怪的问题。

如果你看一下下面的代码,在函数中,' findSolution'我正在通过一个阵列 - ' board'。 然后我在这一行中获取了这个数组的副本 -

let boardCp=board.slice(); //Board is an array of arrays (idea is to never modify the original board object) 

然后将此副本传递给另一个函数进行修改。 当该函数修改此副本时,原始数组(在这种情况下为' board')应保持不变 - 对吗? 但令人惊讶的是,我发现原始阵列也在被修改。

有人可以帮我理解为什么会这样吗?如果我需要提供更多详细信息,请与我们联系。



	var solveNQueens=function(A)
	{
		var retArr=[];
		
		var board=[];
		for(var i=0;i<A;i++)
		{
			var row=[];
			for(var j=0;j<A;j++)
			{row.push('.');}
		board.push(row);
		}				
		
		findSolution(board.slice(),A,0,{},retArr);	
		return retArr;
	}

	var findSolution=function(board,boardSize,rowNum,queenpositions,retArr)
	{		
		for(var j=0;j<boardSize;j++)
		{
			if(rowNum==0)
				queenpositions={};

			if(isSafeToPlace(rowNum,j,queenpositions))
				{		
				var foundSolutionsToOtherQueens=true;
				queenpositions[rowNum]=j;   
				var nextRowNum=rowNum+1;
				if(nextRowNum<boardSize)
				foundSolutionsToOtherQueens=findSolution(board,boardSize,nextRowNum,Object.assign({},queenpositions),retArr);
			    else
				{
				  debugger;
				  let boardCp=board.slice();
			      retArr.push(convertQueenPositionToArray(boardCp,queenpositions));				  
				  }
		
				if(!foundSolutionsToOtherQueens)
					delete queenpositions[rowNum];
				
			}
	     }		 
		 return false;
	}
	
	var convertQueenPositionToArray=function(boardCp,queenpositions)
	{
		for(var i=0;i<boardCp.length;i++)
		{			
			var row=boardCp[i];
			for(var j=0;j<row.length;j++)
			{
			if(queenpositions.hasOwnProperty(i) && j==queenpositions[i])	
				row[j]='Q';
			}
		}
		return boardCp;
	}
	
	var isSafeToPlace=function(rowNum,j,existingQueenpositions)
	{
		for(var prop in existingQueenpositions)
		{
			var colmn=existingQueenpositions[prop];			
			if(colmn===j || colmn==(j-(rowNum-prop)) || colmn==(j+(rowNum-prop)))
				return false;			
		}
		return true;
	}
&#13;
&#13;
&#13;

1 个答案:

答案 0 :(得分:2)

slice方法不进行深层复制。

它只复制数组的第一层(仅限sting和数字)。

让我们考虑以下示例:

const nestedArray = [
  1,
  [2, 3],
  { y1: 4, y2: 5},
];

const cloneArray = nestedArray.slice();

// this is safe
cloneArray[0] = 'new value 1';
console.log(nestedArray[0]); // expect 1

// cloneArray[1] is a pointer to the original array
cloneArray[1][0] = 'new value 2';
console.log(nestedArray[1]); // expect 2, got 'new value 2'

// cloneArray[2] s a pointer to the original object
cloneArray[2].y1 = 'new value 4';
console.log(nestedArray[2]); // expect { y1: 4, y2: 5}, got { y1: 'new value 4', y2: 5}

  • 如果您需要嵌套数组或对象的深层副本,则必须递归执行或使用第三方库,例如 lodash var cloneArray = _.cloneDeep(nestedArray)

  • 另一种快捷方式是JSON.parse(JSON.stingify(nestedArray))