Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/376.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 为什么不是';当我的变量为时,我的对象是否私有?_Javascript_Private Members - Fatal编程技术网

Javascript 为什么不是';当我的变量为时,我的对象是否私有?

Javascript 为什么不是';当我的变量为时,我的对象是否私有?,javascript,private-members,Javascript,Private Members,我正在尝试将对象设为私有对象,但不确定如何做到这一点。正如您所看到的,name变量是private,我不能编辑它,但是当它涉及到我返回的对象时,我可以编辑它。不过,我不希望这成为可能。 我对javascript中的面向对象和私有方法非常陌生,所以有人能告诉我这里的对与错吗我怎样才能解决这个问题? 谢谢 这是可能发生的,因为在JS中,对象通过链接传递-并没有从源对象处理 只需尝试复制对象: var User = function() { var name = 'bob'; this.ge

我正在尝试将对象设为私有对象,但不确定如何做到这一点。正如您所看到的,name变量是private,我不能编辑它,但是当它涉及到我返回的对象时,我可以编辑它。不过,我不希望这成为可能。 我对javascript中的面向对象和私有方法非常陌生,所以有人能告诉我这里的对与错吗我怎样才能解决这个问题? 谢谢


这是可能发生的,因为在JS中,对象通过链接传递-并没有从源对象处理

只需尝试复制对象:

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 }

字符串等基本值是通过值传递的。这意味着当您为变量分配字符串时,您正在为变量设置字符串的实际值

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


在您的示例中,您的
getOther
方法返回对
otherInfo
对象的引用。因此,当您将
age
属性设置为“wtf”时,您是在变量引用的对象上设置它。

您还声明了
var name
两次

当您
var person=new User()时
a
var name
在用户函数的范围内声明

当您
var name=person.getName()时您正在用户函数范围外声明一个同名变量

所以,当你
name='Jenny'解释器将此字符串与用户范围之外的
名称
变量相关联

一般来说,使用具有通用名称(名称、标题、id等)的变量作为全局变量是一个坏主意。我将使用
this.
引用对象属性,并定义
setters
以及
getter
。您还可以忽略
设置器
,并使用
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,
    };
}

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

如果不希望更改
person.getOther()
的返回值以更改
otherInfo
的值,则需要返回它的副本。这并不是真正复制对象。相反,它使用
this.otherInfo
作为新对象的原型。谢谢,我已经修复了它。
this.getOther = function() {
    return {
        age: 20,
        human: true,
    };
}