将对象分配给变量

时间:2016-12-22 11:18:04

标签: javascript node.js express

我的ExpressJS应用程序中的一个非常奇怪的问题。

我的代码:

console.log(req.user); // { user_id: '12345', name: 'Mr Example' }
var set = {};
set = req.user;
set['test'] = "testing";

console.log(req.user); // { user_id: '12345', name: 'Mr Example', test: 'testing' }
console.log(set); // { user_id: '12345', name: 'Mr Example', test: 'testing' }

为什么console.log(req.user)也会输出test属性和值?它似乎是在复制set变量所做的任何事情。这是为什么?

4 个答案:

答案 0 :(得分:2)

这是完全正常的...如果你set = <obj>它只添加对该对象的引用,而不是创建新对象。

只需改变:

set = req.user;

为:

set = Object.create(req.user);

请注意,它不会重写旧值,您必须自己做...

for (var k in req.user) { set[k] = req.user[k]; }

JSFiddle

或更短的版本:

var set = Object.assign({}, req.user);

这个将复制所有值。

JSfiddle

答案 1 :(得分:1)

这一行:

set = req.user;

使set引用req.user引用的同一个对象(丢弃它以前用于上一行中创建的对象的引用)。从那时起,它们只是获取内存中相同对象的方法。很自然地,通过一个变量访问该对象所做的任何更改也可以通过另一个变量看到,因为它们都只是引用一个对象。

请记住,引用对象的变量或属性中的值不是实际对象,它是一个名为对象引用的值,它告诉JavaScript引擎对象在内存中的其他位置。同一个对象可以有很多不同的变量和属性引用它。

让我们抛出一些ASCII艺术(好吧,Unicode艺术):

var set = {}行之后,你有了这个内容(遗漏了一些细节):

         +−−−−−−−−−−+     
req−−−−−>| (object) |     
         +−−−−−−−−−−+     +−−−−−−−−−−−−−−−−−−−−+
         | user     |−−−−>|      (object)      |
         +−−−−−−−−−−+     +−−−−−−−−−−−−−−−−−−−−+
                          | user_id: "12345"   |
         +−−−−−−−−−−+     | name: "Mr Example" |
set−−−−−>| (object) |     +−−−−−−−−−−−−−−−−−−−−+
         +−−−−−−−−−−+     

但是你做set = req.user,所以你有这个:

         +−−−−−−−−−−+     
req−−−−−>| (object) |     
         +−−−−−−−−−−+     +−−−−−−−−−−−−−−−−−−−−+
         | user     |−−+−>|      (object)      |
         +−−−−−−−−−−+  |  +−−−−−−−−−−−−−−−−−−−−+
                       |  | user_id: "12345"   |
set−−−−−−−−−−−−−−−−−−−−+  | name: "Mr Example" |
                          +−−−−−−−−−−−−−−−−−−−−+

...而set过去引用的对象不再有任何引用它的东西,所以它可以被垃圾收集。

当然,set['test'] = "testing"会这样做:

         +−−−−−−−−−−+     
req−−−−−>| (object) |     
         +−−−−−−−−−−+     +−−−−−−−−−−−−−−−−−−−−+
         | user     |−−+−>|      (object)      |
         +−−−−−−−−−−+  |  +−−−−−−−−−−−−−−−−−−−−+
                       |  | user_id: "12345"   |
set−−−−−−−−−−−−−−−−−−−−+  | name: "Mr Example" |
                          | test: "Testing"    |
                          +−−−−−−−−−−−−−−−−−−−−+

答案 2 :(得分:0)

因为javascript中的对象通过引用分配

这意味着当你写

set = req.user;

您说“我希望set变量和req.user变量引用完全相同的对象。”

因此,如果setreq.user都指向同一个对象,那么更改一个上的值会改变另一个上的值。

当您console.log req.userset时,您正在两次记录完全相同的对象。

答案 3 :(得分:-1)

set 是javascript中的关键词,它创建对现有对象的新引用。如果要复制变量,请使用其他变量引用而不是set。

console.log(req.user); 
var userData = {};
userData = req.user;
userData['test'] = "testing";

console.log(req.user); 
console.log(userData);