为什么我的对象不是私人的,当我的变量是?

问题描述:

我试图让一个对象是私人的,但不知道如何做到这一点。正如你所看到的名称变量是私有的,我不能编辑它,但是当涉及到我返回的对象时,我可以编辑它。不过,我不希望这是可能的。 在JavaScript中我很新的面向对象和私有方法,所以有人可以告诉我什么是对的和在这里。 :)我该如何解决这个问题? 谢谢!为什么我的对象不是私人的,当我的变量是?

var User = function() { 

    var name = 'bob'; 
    this.getName = function() { 
    return name; 
    } 

    var otherInfo = { 
    age: 20, 
    human: true, 
    } 
    this.getOther = function() { 
    return otherInfo; 
    } 

} 

var person = new User(); 

var name = person.getName(); 
name = 'jenny'; 
console.log(person.getName()); // bob 

var other = person.getOther(); 
other.age = 'wtf?'; 
console.log(person.getOther()); // { age: 'wtf?', human: true } 
+0

如果您不想更改'person.getOther()'的返回值来更改'otherInfo'的值,那么您需要返回它的一个副本。 – forgivenson

+0

我该怎么做? –

+0

http://*.com/questions/728360/most-elegant-way-to-clone-a-javascript-object – Jonathan

这是发生,因为在JS对象通过链接 - 没有从源对象coped。

刚刚尝试复制对象:

如字符串
var User = function() { 

    var name = 'bob'; 
    this.getName = function() { 
    return name; 
    } 

    var otherInfo = { 
    age: 20, 
    human: true, 
    } 
    this.getOther = function() { 
    return Object.assign({}, otherInfo); 
    } 

} 

var person = new User(); 

var name = person.getName(); 
name = 'jenny'; 
console.log(person.getName()); // bob 

var other = person.getOther(); 
other.age = 'wtf?'; 
console.log(person.getOther()); // { age: 20, human: true } 
+0

这并不是真正的复制对象。相反,它使用'this.otherInfo'作为新对象的原型。 – forgivenson

+0

好的。它是不同的快速答案。我将其更改为Object.assign –

+0

您的代码仍然无法使用。测试一下。 – forgivenson

原始值按值传递。这意味着当您将一个字符串分配给您的变量时,您将该字符串的实际值设置为该变量。

对象是通过引用传递。这意味着当您将一个对象分配给您的变量时,您只需将对象的引用,而不是它的实际值。如果您有一个对象并将其分配给6个不同的变量,则每个变量将具有对同一个基础对象的引用

在您的示例中,您的getOther方法正在将参考返回到otherInfo对象。所以,当你将age属性设置为“wtf”时,你将它设置在你的变量引用的对象上。

您还声明var name两次。

当您在用户功能的范围内声明var person = new User(); a var name时。

当你var name = person.getName();你声明一个变量具有相同的名称超出了用户功能的范围。

因此,当您name = 'Jenny';解释器将此字符串name变量关联到用户范围之外。

一般来说,将通用名称(名称,标题,ID,...)这样的变量用作全局变量是一个坏主意。我将使用this.来引用对象属性,并定义setters以及getters。您也可以忽略setters并参照用户属性与person.,像这样:

function User() { 
    this.name = 'bob'; 
    this.getName = function() { 
    return this.name; 
    } 

    this.otherInfo = { 
    age: 20, 
    human: true, 
    } 
    this.getOther = function() { 
    return this.otherInfo; 
    } 

} 

var person = new User(); 

console.log(person.getName()); // bob 
person.name = 'jenny'; 
console.log(person.getName()); // jenny 

console.log(person.getOther(); // { age: 20, human: true } 
person.otherInfo.age = 'wtf?'; 
console.log(person.getOther()); // { age: 'wtf?', human: true } 

您不必在Javascript对象范围“私人”的事情。从外部隐藏事物的唯一方法是使用函数范围,就像您使用name(函数User中的局部变量)所做的那样。

要每次返回一个内容相同的对象,可以在该函数内部创建该对象。与此类似,比如:

this.getOther = function() { 
    var otherInfo = { 
     age: 20, 
     human: true, 
    } 
    return otherInfo; 
} 

或者只是:

this.getOther = function() { 
    return { 
     age: 20, 
     human: true, 
    }; 
} 

在这两种情况下,您将创建与每个调用一个新的对象。