Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/spring/11.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 getter可以设置私有变量_Javascript_Oop - Fatal编程技术网

Javascript getter可以设置私有变量

Javascript getter可以设置私有变量,javascript,oop,Javascript,Oop,我想我误解了JavaScript中的OOP。据我所知,使用自己的getter和setter函数设置私有变量的目的是保护它不受程序中其他地方意外更改的影响。但我发现很容易使用getter函数意外地更改私有变量,这意味着我一定做错了什么 function Phone(os) { this.os = os; var _phoneBook = []; // phoneBook is intended to be private this.newNumber = function(phoneN

我想我误解了JavaScript中的OOP。据我所知,使用自己的getter和setter函数设置私有变量的目的是保护它不受程序中其他地方意外更改的影响。但我发现很容易使用getter函数意外地更改私有变量,这意味着我一定做错了什么

function Phone(os) {
  this.os = os;
  var _phoneBook = []; // phoneBook is intended to be private
  this.newNumber = function(phoneNumber) { // set new number
    _phoneBook.push(phoneNumber);
  }
  this.listNumbers = function() { // get all numbers
    return _phoneBook;
  }
}

var andy = new Phone("Android");
andy.newNumber("555-123-4567");
console.log(andy.listNumbers()); // => ["555-123-4567"]
// You shouldn't be able to set a private property through a getter function, but you can.
var extendedPhoneBook = andy.listNumbers().push("123-456-7890"); 
console.log(andy.listNumbers()); // => ["555-123-4567", "123-456-7890"]

您可以考虑将函数<代码> ListNoS> /代码>改为<代码>枚举数枚举器>代码>,该函数使用一个函数,该函数为列表中的每个编号传递一个字符串来隐藏内部数组,如:

function Phone(os) {
  this.os = os;
  var _phoneBook = []; // phoneBook is intended to be private
  this.newNumber = function(phoneNumber) { // set new number
    _phoneBook.push(phoneNumber);
  }
  this.enumerateNumbers = function(cb) { // get all numbers
    for (var idx in _phoneBook) {
      cb(_phoneBook[idx]);
    }
  }
}

var andy = new Phone("Android");
andy.newNumber("555-123-4567");

andy.enumerateNumbers(function(num) { console.log(num); })
function Phone(os) {
  this.os = os;
  var _phoneBook = []; // phoneBook is intended to be private
  this.newNumber = function(phoneNumber) { // set new number
    _phoneBook.push(phoneNumber);
  }
  this.listNumbers = function() { // get all numbers
    return _phoneBook.slice(0);
  }
}

该数组作为引用传递,因此在调用
listNumbers()
时,将实际数组返回到外部。您可以使用以下内容返回阵列的副本:

function Phone(os) {
  this.os = os;
  var _phoneBook = []; // phoneBook is intended to be private
  this.newNumber = function(phoneNumber) { // set new number
    _phoneBook.push(phoneNumber);
  }
  this.enumerateNumbers = function(cb) { // get all numbers
    for (var idx in _phoneBook) {
      cb(_phoneBook[idx]);
    }
  }
}

var andy = new Phone("Android");
andy.newNumber("555-123-4567");

andy.enumerateNumbers(function(num) { console.log(num); })
function Phone(os) {
  this.os = os;
  var _phoneBook = []; // phoneBook is intended to be private
  this.newNumber = function(phoneNumber) { // set new number
    _phoneBook.push(phoneNumber);
  }
  this.listNumbers = function() { // get all numbers
    return _phoneBook.slice(0);
  }
}

对象(因此数组)是可变的。如果公开对象或数组,则可以对其进行更改。您可以返回一个副本,但是如果数组包含更多对象,这也不会有帮助。创建深度副本似乎不切实际。在你的情况下,如果你真的认为有必要,一个浅拷贝似乎就足够了。没有人可以用不同的数组来交换你的
\u电话簿
,但是如果你不返回数组的副本,那么每个人都可以更改它的条目。(在任何其他将对象作为引用传递的语言中,你都有同样的“问题”,例如Java),这会有所帮助。那么,解决方案是“您的getter函数应该始终包含返回变量副本而不是原始变量的代码”,还是缺少一个更大的模式?我这样问是因为我一直在阅读JavaScript中的面向对象编程,而我的资料似乎都没有提到这一点。