私有成员在javascript中是否安全?
我正在学习JavaScript oop课程。本课程介绍如何在对象内部声明私有变量,以用于无法从外部更改的情况,如密码和银行帐户。对私有变量的唯一访问是通过具有私有变量访问权限的public方法。然后给出了演示代码来说明这一点私有成员在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
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()代码>仍然会给你10Bird.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;
)是函数的局部变量,两者是不同的。如果我