Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/oop/2.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_Oop_Private - Fatal编程技术网

私有成员在javascript中是否安全?

私有成员在javascript中是否安全?,javascript,oop,private,Javascript,Oop,Private,我正在学习JavaScript oop课程。本课程介绍如何在对象内部声明私有变量,以用于无法从外部更改的情况,如密码和银行帐户。对私有变量的唯一访问是通过具有私有变量访问权限的public方法。然后给出了演示代码来说明这一点 function Bird() { let hatchedEgg = 10; // private variable /* publicly available method that a bird object can use */ this.getHatc

我正在学习JavaScript oop课程。本课程介绍如何在对象内部声明私有变量,以用于无法从外部更改的情况,如密码和银行帐户。对私有变量的唯一访问是通过具有私有变量访问权限的public方法。然后给出了演示代码来说明这一点

function Bird() {
  let hatchedEgg = 10; // private variable

  /* publicly available method that a bird object can use */
  this.getHatchedEggCount = function() { 
    return hatchedEgg;
  };
}
let ducky = new Bird();
ducky.getHatchedEggCount(); // returns 10
我不明白的是hatchedEgg变量如何被称为安全变量。 作为一名用户/黑客,我所要做的就是猜测从函数getHatchedegCount()返回的变量名。在本例中,hatchedEgg(这对于黑客来说并不太难),然后我可以使用这一行修改私有变量

Bird.hatchedEgg = 20;
console.log(Bird) // returns { [Function: Bird] hatchedEgg : 20 }
我错过什么了吗

//-------------- Clarification Edit
显然问题出在freecodecamp控制台(一个Bug)上,它正在更改私有变量的值。
如果你想,你可以尝试粘贴在这个链接上面的代码,你会看到

直接调用
ducky.hatchedgg
(我想你是指这个而不是
Bird.hatchedgg
)不会给你任何结果(
准确地说是未定义的
)。这就是这个例子的全部要点,即私有变量不能直接从外部访问。它们是通过一种方法访问的,而这种方法又可能/不可能暴露于外部。安全来自于此

更新我再次阅读了这个问题,您所做的是:将属性
hatchedeg
附加到
Bird
并为其设置值

Bird.hatchedEgg=20

但是,该
hatchedEgg
设hatchedEgg=10不同

ducky.gethatchedegcount()仍然会给你10
Bird.hatchedgg
在将属性
hatchedgg
附加到对象
Bird
时将为您提供
20
,该属性与函数
Bird
中声明的
hatchedgg
不同


另外,
函数
s是一类对象,您可以像处理任何其他对象一样向其添加/删除属性。然而,在上一篇文章中,我故意试图区分
函数
鸟和
对象
鸟,以便把事情弄清楚。这就像说,
array
s也是
对象。但是你在谈话中保持了一种距离,以便简单地描述事情。无论如何,我认为这会导致一些混乱。

我认为您对正在创建的变量以及如何访问每个变量感到有点困惑

您可以从一个函数开始:

function Bird() {
  let hatchedEgg = 10;

  this.getHatchedEggCount = function () {
    return hatchedEgg;
  };
}
此函数没有任何属性

调用此函数时,它只是将
gethatchedegcount
属性附加到
this
对象。
gethatchedegcount
属性本身就是一个函数,它引用了
Bird
函数运行时创建的
hatchedgg
变量

因此,我们可以这样做:

// We call the 'Bird' function.
// As we are using the 'new' keyword, we create an empty context for the function.
// The empty context is referenced using the 'this' keyword inside the 'Bird' function.
// We assign 'getHatchedEggCount' as a method on the 'this' empty object
// We then return the 'this' object
// The 'ducky' variable now points to the returned 'this' object
// Therefore the 'ducky' variable is an object with a 'getHatchedEggCount' method
let ducky = new Bird();
控制台日志记录提供以下输出:

console.log(ducky);
// Output: Bird { getHatchedEggCount: [Function] }

console.log(ducky.hatchedEgg);
// Output: undefined

console.log(ducky.getHatchedEggCount());
// Output: 10
这是意料之中的事情,因为
ducky
是一个只有一个属性的对象,即
gethatchedegcount
方法

但最重要的是,请注意当我们记录以下内容时会发生什么:

console.log(Bird);
// Output: [Function: Bird]

console.log(Bird.hatchedEgg);
// Output: undefined

console.log(Bird.getHatchedEggCount);
// Output: undefined
我们看到,
Bird
函数实际上是一个空对象。它没有属性(我们自己分配的),因此
Bird.hatchedeg
不存在

那么,为什么调用
ducky.gethatchedegcount()
时可以访问
hatchedEgg
变量呢?这是由于闭包是如何工作的,但这是离题的。不用说,
hatchedEgg
变量只能由
gethatchedegcount
函数访问

现在,如果我们说:

    Bird.hatchedEgg = 20;
我们正在为
Bird
函数添加一个全新的属性。因此,我们可以控制台日志:

console.log(Bird);
// Output: [Function: Bird] { hatchedEgg: 20 }

console.log(Bird.hatchedEgg);
// Output: 20
我们在
Bird
函数中添加了一个以前不存在的新
hatchedeg
属性

但是请注意,这与
gethatchedegcount
函数使用的
hatchedEgg
变量的属性不同

原始的
hatchedgg
变量是在
Bird
函数中创建的,可以在函数体中访问,但不是
Bird
函数对象的属性,因此不能通过执行
Bird.hatchedgg
来访问。你看到区别了吗

例如,运行以下代码:

function Bird() {
  let hatchedEgg = 10;

  this.getHatchedEggCount = function () {
    return hatchedEgg;
  };
}

Bird.hatchedEgg = 20;
console.log(Bird.hatchedEgg);
// Output: 20

let ducky = new Bird();
console.log(ducky.getHatchedEggCount());
// Output: 10

您知道为什么值为
10
hatchedeg
变量仍然无法访问吗?它与
Ducky.hatchedEgg

不同,正如freecodecamp主题中所述,它被称为闭包。只需使用非常简单的编程概念来考虑:

函数内部声明的变量的作用域是该函数,因此无法从函数外部访问这些变量。这不仅适用于JavaScript,也适用于所有其他语言

至于为什么我们可以从外部获得作用域变量的值,闭包的神奇之处在于。既然问题没有提到“结束”这个词,更不用说问它了,我就不在这里讨论结束的细节了

至于你说的黑客可以用来破解的代码,那条线

Bird.hatchedEgg = 20;
仅在对象内创建属性。这里的另一个基本概念是函数
Bird
也是JavaScript中的第一类对象,这意味着它可以像任何其他对象一样具有属性和函数
Bird.hatchedgg
指的是
Bird
对象的属性,而
Bird
函数中声明的变量(使用
让hatchedgg=10;
)是函数的局部变量,两者是不同的。如果我