在 JS 数组中设置对象参数的问题

problem with setting objects parameter in JS array


我喜欢在 JS 数组中生成,该数组将包含具有随机坐标值的 GeoJson 对象。 我开始使用循环将 10 个对象推入数组,这部分工作正常,但是,当我想设置坐标的随机值(因此每个对象都有不同的坐标)时,我收到每个对象的相同坐标。

这是某种传递引用问题吗?如何处理?

我的代码如下所示:

//random number generator
function randomNumber(){
    min = Math.floor(0);
    max = Math.floor(360);
    let coordinateX = Math.floor(Math.random()*(max-min+1))+min;
    let coordinateY = Math.floor(Math.random()*(max-min+1))+min;
    return [coordinateX,coordinateY]
};
//geoJson object structure example
let featureClassObject = {
  "type": "Feature",
  "geometry": {
    "type": "Point",
    "coordinates": [10,10] //these don't like to cooperate 
  },
  "properties": {
    "name": "Dinagat Islands"
  }
}
//generating array and and pushing 10x GeoJson Object
let featuresArray = [];
for (let i=0;i<10;i++){
    featuresArray.push(featureClassObject);
}
//changing the value of coordinates 
featuresArray.forEach((item)=>{
    item.geometry.coordinates=randomNumber();
});

您正在推动同一个物体 10 次。您可以使用 Object.assign.

轻松解决此问题
const featuresArray = [];
for (let i = 0; i < 10; i++) {
    featuresArray.push(Object.assign({}, featureClassObject));
}

这会推送 10 个包含相同数据的不同对象。

使用 Object.assign() 制作嵌套对象的副本,这样您就不仅仅是引用指针了:

function randomNumber(){
    min = Math.floor(0);
    max = Math.floor(360);
    let coordinateX = Math.floor(Math.random()*(max-min+1))+min;
    let coordinateY = Math.floor(Math.random()*(max-min+1))+min;
    return [coordinateX,coordinateY]
};
//geoJson object structure example
let featureClassObject = {
  "type": "Feature",
  "geometry": {
    "type": "Point",
    "coordinates": [10,10]
  },
  "properties": {
    "name": "Dinagat Islands"
  }
}
//generating array and and pushing 10x GeoJson Object
let featuresArray = [];
for (let i=0;i<10;i++){
    featureClassCopy = Object.assign({}, featureClassObject);
    featureClassCopy.geometry = Object.assign({}, featureClassCopy.geometry);
    featuresArray.push(featureClassCopy);
}
//changing the value of coordinates 
featuresArray.forEach((item)=>{
    item.geometry.coordinates=randomNumber();
});

所以一般来说,以上是一种通过引用传递的问题。
如何查看?

array[0]===array[1] 


当高于 returns true 时,这意味着您已经在数组中创建了对一个对象的多个引用。

要处理它,有一种方法 -> 您必须先复制一个对象,然后再将其推送到数组。
复制对象有两种方式:
1。浅复制(不复制对象的嵌套部分并且对于对象的嵌套部分仍然returns参考):
- let copyOfObjectFirstWay = Object.assign({}, objectName);
- let copyOfObjectSecondWay = {...objectName}
2。深度复制(复制整个甚至嵌套部分): - let copyOfObjectDeepWay = JSON.parse(JSON.stringify(objectName)); - 当对象又大又复杂时,这可能会导致一些性能问题。

在我的例子中(来自 Seanonymous 的暗示)我通过使对象生成器函数成为对象的 returns 副本(已解析和字符串化)来解决它。
我的代码

function randomNumber(min, max){
    let random = ((Math.random()*(max-min+1))+min).toFixed(4);
    return random
};

function objectGenerator(){
    let featureClassObject = {
        "type": "Feature",
        "geometry": {
            "type": "Point",
            "coordinates": [10,10]
        },
       "properties": {
            "name": "Dinagat Islands"
        }
    };
    featureClassObject.geometry.coordinates=[randomNumber(20.13666, 21.875), 
    randomNumber(51.87,52.3160)];
    let newFeatureClassObcject= JSON.parse(JSON.stringify(featureClassObject));
    return newFeatureClassObcject;
};

let randomFeatureClassArray= [];
function randomGeometryObjectArrayGenerator(){
    let t0=performance.now();

for (let i=0;i<100;i++){
    randomFeatureClassArray.push(objectGenerator());
};
let t1=performance.now();
console.log(`the array was generated in  ${t1-t0} miliseconds`)
};

randomGeometryObjectArrayGenerator();