Javascript 理解公共/私有实例变量

Javascript 理解公共/私有实例变量,javascript,Javascript,我正在读一篇关于公共/私人方法的文章,无法理解其中的区别 对于私有方法,它说:“私有成员由构造函数生成。构造函数的普通变量和参数成为私有成员。” 对于公共方法,“此技术通常用于初始化公共实例变量。构造函数的此变量用于向对象添加成员。” 正如您所看到的,这两个函数都有一个paramsparamater和一个this.member=param。一个是私有实例变量,另一个是公共实例变量 此变量中没有一个是真正私有的,因为如果实例化容器,则可以访问机密变量: function Container(par

我正在读一篇关于公共/私人方法的文章,无法理解其中的区别

对于私有方法,它说:“私有成员由构造函数生成。构造函数的普通变量和参数成为私有成员。”

对于公共方法,“此技术通常用于初始化公共实例变量。构造函数的
变量用于向对象添加成员。”


正如您所看到的,这两个函数都有一个
params
paramater和一个
this.member=param。一个是私有实例变量,另一个是公共实例变量

此变量中没有一个是真正私有的,因为如果实例化容器,则可以访问机密变量:

function Container(param) {
    this.member = param;
    var secret = 3;
    var that = this;
}

var container = new Container();
console.log(container.secret);
container.secret = "toto";
console.log(container.secret);
console.log(container);
结果如下:

正如您所看到的,您可以在不使用任何“Getter/Setter”的情况下访问secret

如果要使用真正私有的变量执行对象javascript,请参阅本教程:

了解闭包 打开一个新的函数体将创建一个新的作用域。这种作用域在JS中称为闭包。在该范围内创建的变量可以在其所有子范围内访问。这意味着任何
var
创建的变量都将对子函数可见。在本例中,可以在子范围内访问myTemporaryVar

function myParentScope() {
  var myTemporaryVar = "sample";

  function subScope() {
    console.log(myTemporaryVar);
  }

  return subScope();
}
使用带有
new
关键字的函数时,将为当前实例创建一个新闭包。在该构造函数中创建的任何函数都将保持对范围变量的访问。在下一个示例中,函数sayHi可以访问临时变量myName

function Person(name) {
  var myName = name;
  this.sayHi = function() {
    console.log("Hi, my name is " + myName + ".");
  };
}

p = new Person("Bob");
p.sayHi(); // Hi, my name is Bob.
实际上,传递的参数与
var
创建的变量相同。构造函数的参数可以在任何子函数中访问。因此,前面的示例可以简化为:

function Person(name) {
  this.sayHi = function() {
    console.log("Hi, my name is " + name + ".");
  };
}

p = new Person("Bob");
p.sayHi(); // Hi, my name is Bob.
这是JavaScript的一个非常独特的功能,因为这意味着
var
-创建的变量在函数结束后仍然存在,只要还有方法访问它们

基于类的面向对象隐私仿真 闭包可以被“滥用”来创建具有getter和setter函数的私有成员

function Person(name) {
  this.getName = function() {
    return name;
  };

  this.setName = function(newname) {
    name = newname;
  };
}

p = new Person("Bob");
console.log(p.getName()); // "Bob"
p.setName("Alice");
console.log(p.getName()); // "Alice"
p.name; // undefined
为什么这不是真正的隐私 为了访问
var
-变量,必须在构造函数中创建getter和setter。以通用原型扩展方式添加的方法无法访问它们。原型方法也必须使用setter和getter,这使得这些变量的隐私变得毫无用处

Person.prototype.sayGoodMorning = function() {
  console.log("Good morning, my name is " + this.getName() + ".");
}
在方法中直接访问变量的唯一方法是在构造函数中实际创建它。但是将所有方法放在构造函数中效率极低,因为将为每个实例创建方法的新副本。这就是为什么许多人喜欢简单地使用自定义符号来识别潜在的私有成员。建议在变量名的末尾添加下划线

function Person(name) {
  this.name_ = name;
}

Person.prototype.getName = function() {
  return this.name_;
}

Person.prototype.setName = function(name) {
  this.name_ = name;
}

Person.prototype.sayGoodMorning = function() {
  console.log("Good morning, my name is " + this.name_ + ".");
}

程序员有责任不愚蠢地访问潜在的私人成员。请注意,这与Crockford的观点完全矛盾,但每个人都有自己的观点。我在Python之后学习了JS,所以下划线隐私对我来说是第二天性。

在这两种情况下,
this.member
是public
var secret
是唯一的私有变量。但是您不能真正将其称为私有
实例变量
,因为它仅在构造函数内部可用。这是JS——抛开所有其他编程语言中关于经典继承的知识,学习原型继承以及可以和不能使用它做什么。首先:JS中没有纯粹的私有实例变量。教程指出,
这个构造函数有三个私有实例变量:param、secret和that。
…javascript中没有“private”。@JaromandaX-虽然我不是与Crockford争论的人,严格地说,它们不是真正的
实例
变量。如果使用方法的
原型
,为了扩展其功能,您将无法访问在构造函数中创建的方法原型中任何方法的
私有实例变量
,这意味着它们不是真正的
实例
变量。您如何访问secret?我可以使用容器访问secret。member@OrcusW这根本不是在访问秘密变量。@JacqueGoupil它在访问,正如你所看到的,我只是获取对象并更改变量。你看不见,但你可以改变它@OrcusW您正在访问
成员
变量,该变量是公共的。您从未访问过
secret
变量。这不包括工厂模式和类似的内容,但我想我有点忘乎所以了。
Person.prototype.sayGoodMorning = function() {
  console.log("Good morning, my name is " + this.getName() + ".");
}
function Person(name) {
  this.name_ = name;
}

Person.prototype.getName = function() {
  return this.name_;
}

Person.prototype.setName = function(name) {
  this.name_ = name;
}

Person.prototype.sayGoodMorning = function() {
  console.log("Good morning, my name is " + this.name_ + ".");
}