Javascript通过引用或值分配数组元素

Posted

技术标签:

【中文标题】Javascript通过引用或值分配数组元素【英文标题】:Javascript assign array elements by reference or by value 【发布时间】:2017-04-15 06:45:46 【问题描述】:

有没有办法通过引用而不是值来明确设置数组元素?

比如这个方法通过值来设置数组元素:

方法一

var pushes = [2,1]
for(var i=0; i<pushes.length; i++)

   vm.allEmployeesOnJob[i] = vm.allEmployees[pushes[i]];                  

并且这个方法通过引用设置数组元素:

方法 2

var pushes = [2,1]
vm.allEmployeesOnJob = [
                vm.allEmployees[2],
                vm.allEmployees[1]                
              ];

我的用例:

我正在使用 angular-bootstrap-duallistbox,为了正确初始化两个列表框,“ng-model”数组必须通过引用引用“ng-options”数组元素。这是由于我阅读过的解释中“选择”DOM 元素的行为所致。我知道第二种是通过引用设置的原因是因为列表框使用该方法正确更新,而使用第一种方法没有正确更新。

会有什么不同?

有没有办法通过引用以编程方式将数组元素显式设置为另一个数组的元素?

编辑:

vm.allEmployees 是一个员工对象数组。

vm.allEmployees 的内容:

[        
      "employeeId":1,
      "firstName":"Bill",
      "lastName":"Test",
      "email":null,
      "phoneNumber":null,
      "street":"1234 Sesame",
      "city":"New York City",
      "state":"New York",
      "zip":"34555",
      "activeFlag":true,
      "homeLocationId":2,
      "homeLocation":  
         "locationId":2,
         "customerId":2,
      ,
      "displayName":"Bill Test - Newaygo"    ,    
   
      "employeeId":2,
      "firstName":"Bob",
      "lastName":"Test",
      "email":null,
      "phoneNumber":null,
      "street":"1234 Sesame",
      "city":"New York City",
      "state":"New York",
      "zip":"34555",
      "activeFlag":true,
      "homeLocationId":2,
      "homeLocation":  
         "locationId":2,
         "customerId":2,
      ,
      "displayName":"Bob Test -  Newaygo"    ,    
   
      "employeeId":4,
      "firstName":"John",
      "lastName":"Doe",
      "email":"testemployee@qas.com",
      "street":"1234 Sesame St",
      "city":"New York City",
      "state":"New York",
      "zip":"34555",
      "activeFlag":true,
      "homeLocationId":2,
      "homeLocation":  
         "locationId":2,
         "customerId":2,
      ,
      "displayName":"John Doe -  Newaygo"    ,    
   
      "employeeId":5,
      "firstName":"Bill",
      "lastName":"Peterson",
      "email":"bpeterson@test.com",
      "street":"1234 test",
      "city":"test city",
      "state":"Maine",
      "zip":"298379283",
      "activeFlag":false,
      "homeLocationId":2,
      "homeLocation":  
         "locationId":2,
         "customerId":2,
      ,
      "displayName":"Bill Peterson -  Newaygo"    ,    
   
      "employeeId":6,
      "firstName":"Jim",
      "lastName":"Super",
      "email":"jsuper@qas.com",
      "phoneNumber":"459-456-4455",
      "street":"1234 Sesame St",
      "city":"New York City",
      "state":"New York",
      "zip":"34555",
      "activeFlag":true,
      "homeLocationId":2,
      "homeLocation":  
         "locationId":2,
         "customerId":2,
      ,
      "displayName":"Jim Super -  Newaygo"     ]

【问题讨论】:

这与 javascript 本身关系不大,而更多地与 AngularJS 的 ng-model 观察其价值的方式有关。我建议editing 您的问题和标题,以更清楚地表明您对 AngularJS 的使用。您还可以展示如何为这两个选择绑定 ng-modelng-options 关于角度部分的好点@MikeMcCaughan。但是,问题的 javascript 部分是我的问题的主要关注点。斯科特在下面的回答回答了这个问题,所以我想如果我不能让它工作,我可能会把这个问题的 Angular 部分留给另一个帖子。 【参考方案1】:

在 JavaScript 中,对象是通过引用来引用的,而所有其他值(无论它们是否在数组中)都是通过值引用的。您可以将您的值存储在一个对象中,并在需要获得此行为时引用/传递它。

您的以下两种方法都使用对象并具有按引用引用。这两个 sn-ps 验证:

方法一

var vm = ;

// Here, the contents of the array are ojbects (by reference)
vm.allEmployees = [        
      "employeeId":1,
      "firstName":"Bill",
      "lastName":"Test",
      "email":null,
      "phoneNumber":null,
      "street":"1234 Sesame",
      "city":"New York City",
      "state":"New York",
      "zip":"34555",
      "activeFlag":true,
      "homeLocationId":2,
      "homeLocation":  
         "locationId":2,
         "customerId":2,
      ,
      "displayName":"Bill Test - Newaygo"    ,    
   
      "employeeId":2,
      "firstName":"Bob",
      "lastName":"Test",
      "email":null,
      "phoneNumber":null,
      "street":"1234 Sesame",
      "city":"New York City",
      "state":"New York",
      "zip":"34555",
      "activeFlag":true,
      "homeLocationId":2,
      "homeLocation":  
         "locationId":2,
         "customerId":2,
      ,
      "displayName":"Bob Test -  Newaygo"    ,    
   
      "employeeId":4,
      "firstName":"John",
      "lastName":"Doe",
      "email":"testemployee@qas.com",
      "street":"1234 Sesame St",
      "city":"New York City",
      "state":"New York",
      "zip":"34555",
      "activeFlag":true,
      "homeLocationId":2,
      "homeLocation":  
         "locationId":2,
         "customerId":2,
      ,
      "displayName":"John Doe -  Newaygo"    ,    
   
      "employeeId":5,
      "firstName":"Bill",
      "lastName":"Peterson",
      "email":"bpeterson@test.com",
      "street":"1234 test",
      "city":"test city",
      "state":"Maine",
      "zip":"298379283",
      "activeFlag":false,
      "homeLocationId":2,
      "homeLocation":  
         "locationId":2,
         "customerId":2,
      ,
      "displayName":"Bill Peterson -  Newaygo"    ,    
   
      "employeeId":6,
      "firstName":"Jim",
      "lastName":"Super",
      "email":"jsuper@qas.com",
      "phoneNumber":"459-456-4455",
      "street":"1234 Sesame St",
      "city":"New York City",
      "state":"New York",
      "zip":"34555",
      "activeFlag":true,
      "homeLocationId":2,
      "homeLocation":  
         "locationId":2,
         "customerId":2,
      ,
      "displayName":"Jim Super -  Newaygo"     ]

vm.allEmployeesOnJob = [];

var pushes = [2,1]
for(var i=0; i<pushes.length; i++) 
   vm.allEmployeesOnJob[i] = vm.allEmployees[pushes[i]];                  


// The references are by reference:
console.log("Are objects in allEmployeesOnJob the same references as allEmployees: " + (vm.allEmployeesOnJob[0] === vm.allEmployees[2] && vm.allEmployeesOnJob[1] === vm.allEmployees[1]));

// More evidence:
vm.allEmployees[2].employeeId= 999;
console.log("allEmployees[2].employeeId= 999. allEmployeesOnJob[0].employeeId is now: " + vm.allEmployeesOnJob[0].employeeId);

方法2

var vm = ;
vm.allEmployees = [
    
      "employeeId":1,
      "firstName":"Bill",
      "lastName":"Test",
      "email":null,
      "phoneNumber":null,
      "street":"1234 Sesame",
      "city":"New York City",
      "state":"New York",
      "zip":"34555",
      "activeFlag":true,
      "homeLocationId":2,
      "homeLocation":  
         "locationId":2,
         "customerId":2,
      ,
      "displayName":"Bill Test - Newaygo"    ,    
   
      "employeeId":2,
      "firstName":"Bob",
      "lastName":"Test",
      "email":null,
      "phoneNumber":null,
      "street":"1234 Sesame",
      "city":"New York City",
      "state":"New York",
      "zip":"34555",
      "activeFlag":true,
      "homeLocationId":2,
      "homeLocation":  
         "locationId":2,
         "customerId":2,
      ,
      "displayName":"Bob Test -  Newaygo"    ,    
   
      "employeeId":4,
      "firstName":"John",
      "lastName":"Doe",
      "email":"testemployee@qas.com",
      "street":"1234 Sesame St",
      "city":"New York City",
      "state":"New York",
      "zip":"34555",
      "activeFlag":true,
      "homeLocationId":2,
      "homeLocation":  
         "locationId":2,
         "customerId":2,
      ,
      "displayName":"John Doe -  Newaygo"    ,    
   
      "employeeId":5,
      "firstName":"Bill",
      "lastName":"Peterson",
      "email":"bpeterson@test.com",
      "street":"1234 test",
      "city":"test city",
      "state":"Maine",
      "zip":"298379283",
      "activeFlag":false,
      "homeLocationId":2,
      "homeLocation":  
         "locationId":2,
         "customerId":2,
      ,
      "displayName":"Bill Peterson -  Newaygo"    ,    
   
      "employeeId":6,
      "firstName":"Jim",
      "lastName":"Super",
      "email":"jsuper@qas.com",
      "phoneNumber":"459-456-4455",
      "street":"1234 Sesame St",
      "city":"New York City",
      "state":"New York",
      "zip":"34555",
      "activeFlag":true,
      "homeLocationId":2,
      "homeLocation":  
         "locationId":2,
         "customerId":2,
      ,
      "displayName":"Jim Super -  Newaygo"     ]

var pushes = [2,1]
vm.allEmployeesOnJob = [
                vm.allEmployees[2],
                vm.allEmployees[1]                
              ];

console.log("Are objects the same (by ref)? " + (vm.allEmployeesOnJob[0] === vm.allEmployees[2] && 
           vm.allEmployeesOnJob[1] === vm.allEmployees[1]));

// Further evidence:
vm.allEmployees[2].employeeId  = 999;
console.log("allEmployees[2].employeeId was changed to 999. What is allEmployeesOnJob[0].employeeId now? " + vm.allEmployeesOnJob[0].employeeId);

【讨论】:

既然我引用了 vm.allEmployees 数组中的元素,它们是对象,那么上面的方法 1 不应该仍然通过引用设置 vm.allEmployeesOnJob 中的元素吗? 你能发布更多代码吗?具体vm.allEmployees的内容是什么? @big_water 你的两个方法都是 By Ref 因为allEmployees 存储对象。请参阅我对您的两种方法的测试。 感谢@ScottMarcus。您的测试确实证明两者都是参考。这一定是 angular-bootstrap-duallistbox 以及它如何处理这些对象的问题。

以上是关于Javascript通过引用或值分配数组元素的主要内容,如果未能解决你的问题,请参考以下文章

通过引用或值传递的数组[重复]

Python - 数组复制/分配,numpy的意外'=array [:]'行为

JavaScript中的数组创建

为啥 PHP 数组的元素被引用分配时会被修改?

多次引用数组中的元素并将该元素分配给变量[重复]

与数组中元素的最大异或值(字典树)(小于等于某元素的最大异或值)