javascript 中的私有成员安全吗?
Is a private member secure in javascript?
我正在学习 freecodecamp 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 变量如何被称为安全的。
作为 user/hacker,我所要做的就是猜测从函数 getHatchedEggCount() 返回的变量名。在这种情况下 hatchedEgg (这对黑客来说并不难)然后我可以使用这一行来修改私有变量;
Bird.hatchedEgg = 20;
console.log(Bird) // returns { [Function: Bird] hatchedEgg : 20 }
我是不是漏掉了什么?
//-------------- Clarification Edit
显然问题出在 freecodecamp 控制台(一个错误),它正在更改私有变量的值。
如果你愿意,你可以尝试将上面的代码粘贴到这个 link 中,你会看到。 freecodeConsoleLink
直接调用 ducky.hatchedEgg
(我猜你的意思是这个而不是 Bird.hatchedEgg
)不会给你任何结果(准确地说是 undefined
)。这就是示例的重点,即私有变量不能直接从外部访问。它们是通过一种方法访问的,而这种方法又 be/could 不会暴露在外面。安全来自于此。
Update 我又重新阅读了这个问题,你正在做的是:你将 属性 hatchedEgg
附加到 Bird
并为其设置一个值。
Bird.hatchedEgg = 20
但是,此 hatchedEgg
与函数中最初定义的 let hatchedEgg = 10;
不同。
ducky.getHatchedEggCount();
仍然会给你 10。Bird.hatchedEgg
会给你 20
,因为你将 属性 hatchedEgg
附加到对象 Bird
与函数 Bird
.
中声明的 hatchedEgg
不同
另外,function
s first-class 对象,您可以 add/remove 它的属性,就像您对任何其他对象所做的那样。但是,在最后的post中,我有意试图区分function
Bird和object
Bird,把事情说清楚。这就像在说,array
也是 objects
。但是你在谈话中保持一种区分,以使事情简单化。无论如何,更新这个我认为会导致某种混乱。
我认为您对正在创建的变量以及如何访问每个变量有点困惑。
您从函数开始:
function Bird() {
let hatchedEgg = 10;
this.getHatchedEggCount = function () {
return hatchedEgg;
};
}
此函数没有任何属性。
调用此函数时,它只是将 getHatchedEggCount
属性 附加到 this
对象。 getHatchedEggCount
属性 本身就是一个函数,它引用 Bird
函数 运行s.
时创建的 hatchedEgg
变量
因此我们可以这样做:
// 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
是一个只有一个 属性 的对象 - getHatchedEggCount
方法。
但最重要的是,请注意当我们记录以下内容时会发生什么:
console.log(Bird);
// Output: [Function: Bird]
console.log(Bird.hatchedEgg);
// Output: undefined
console.log(Bird.getHatchedEggCount);
// Output: undefined
我们看到Bird
函数其实是一个空对象。它没有属性(我们自己分配的),因此 Bird.hatchedEgg
不存在!
So why can we access the hatchedEgg
variable when calling ducky.getHatchedEggCount()
? This is due to how closures work, but that is off topic. Needless to say, the hatchedEgg
variable is ONLY accessible to the getHatchedEggCount
function.
现在,如果我们说:
Bird.hatchedEgg = 20;
我们正在为 Bird
函数添加一个全新的 属性。所以我们可以控制台日志:
console.log(Bird);
// Output: [Function: Bird] { hatchedEgg: 20 }
console.log(Bird.hatchedEgg);
// Output: 20
我们在 Bird
函数中添加了一个新的 hatchedEgg
属性,以前不存在!
但是请注意,这 属性 与 getHatchedEggCount
函数使用的 hatchedEgg
变量不同。
原来的hatchedEgg
变量是在Bird
函数内部创建的,可以在函数体内访问,但不是属性 OF Bird
函数对象,因此无法通过 Bird.hatchedEgg
访问。你看出区别了吗?
例如,运行这个代码:
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
的hatchedEgg
变量仍然无法访问了吗?它与 Ducky.hatchedEgg
.
不是同一个变量
如freecodecamp主题中所述,它称为闭包。只需使用非常琐碎的编程概念这样想:
Variables declared inside a function are scoped to that function, there is no way to access those from outside the function. This is not only true for JavaScript, for all other languages.
现在至于为什么我们可以从外部获取该作用域变量的值是闭包的魔法。由于题目没有提到"closure"这个词,更不用说问了,这里就不细说闭包了。
至于你说的黑客可以用来破解它的代码,行
Bird.hatchedEgg = 20;
仅在 对象 Bird
中创建一个 属性。这里的另一个基本概念 - 函数 Bird
也是 JavaScript 中的第一个 class 对象,这意味着它可以像任何其他对象一样具有属性和功能。 Bird.hatchedEgg
指的是Bird
对象的属性,而Bird
函数内部声明的变量(带let hatchedEgg = 10;
)是函数的局部变量,两者是截然不同的。如果该行要更改在函数内声明的局部变量的值,您应该在控制台日志中得到相同的结果 ducky.getHatchedEggCount()
,但您不会。
我正在学习 freecodecamp 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 变量如何被称为安全的。 作为 user/hacker,我所要做的就是猜测从函数 getHatchedEggCount() 返回的变量名。在这种情况下 hatchedEgg (这对黑客来说并不难)然后我可以使用这一行来修改私有变量;
Bird.hatchedEgg = 20;
console.log(Bird) // returns { [Function: Bird] hatchedEgg : 20 }
我是不是漏掉了什么?
//-------------- Clarification Edit
显然问题出在 freecodecamp 控制台(一个错误),它正在更改私有变量的值。 如果你愿意,你可以尝试将上面的代码粘贴到这个 link 中,你会看到。 freecodeConsoleLink
直接调用 ducky.hatchedEgg
(我猜你的意思是这个而不是 Bird.hatchedEgg
)不会给你任何结果(准确地说是 undefined
)。这就是示例的重点,即私有变量不能直接从外部访问。它们是通过一种方法访问的,而这种方法又 be/could 不会暴露在外面。安全来自于此。
Update 我又重新阅读了这个问题,你正在做的是:你将 属性 hatchedEgg
附加到 Bird
并为其设置一个值。
Bird.hatchedEgg = 20
但是,此 hatchedEgg
与函数中最初定义的 let hatchedEgg = 10;
不同。
ducky.getHatchedEggCount();
仍然会给你 10。Bird.hatchedEgg
会给你 20
,因为你将 属性 hatchedEgg
附加到对象 Bird
与函数 Bird
.
hatchedEgg
不同
另外,function
s first-class 对象,您可以 add/remove 它的属性,就像您对任何其他对象所做的那样。但是,在最后的post中,我有意试图区分function
Bird和object
Bird,把事情说清楚。这就像在说,array
也是 objects
。但是你在谈话中保持一种区分,以使事情简单化。无论如何,更新这个我认为会导致某种混乱。
我认为您对正在创建的变量以及如何访问每个变量有点困惑。
您从函数开始:
function Bird() {
let hatchedEgg = 10;
this.getHatchedEggCount = function () {
return hatchedEgg;
};
}
此函数没有任何属性。
调用此函数时,它只是将 getHatchedEggCount
属性 附加到 this
对象。 getHatchedEggCount
属性 本身就是一个函数,它引用 Bird
函数 运行s.
hatchedEgg
变量
因此我们可以这样做:
// 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
是一个只有一个 属性 的对象 - getHatchedEggCount
方法。
但最重要的是,请注意当我们记录以下内容时会发生什么:
console.log(Bird);
// Output: [Function: Bird]
console.log(Bird.hatchedEgg);
// Output: undefined
console.log(Bird.getHatchedEggCount);
// Output: undefined
我们看到Bird
函数其实是一个空对象。它没有属性(我们自己分配的),因此 Bird.hatchedEgg
不存在!
So why can we access the
hatchedEgg
variable when callingducky.getHatchedEggCount()
? This is due to how closures work, but that is off topic. Needless to say, thehatchedEgg
variable is ONLY accessible to thegetHatchedEggCount
function.
现在,如果我们说:
Bird.hatchedEgg = 20;
我们正在为 Bird
函数添加一个全新的 属性。所以我们可以控制台日志:
console.log(Bird);
// Output: [Function: Bird] { hatchedEgg: 20 }
console.log(Bird.hatchedEgg);
// Output: 20
我们在 Bird
函数中添加了一个新的 hatchedEgg
属性,以前不存在!
但是请注意,这 属性 与 getHatchedEggCount
函数使用的 hatchedEgg
变量不同。
原来的hatchedEgg
变量是在Bird
函数内部创建的,可以在函数体内访问,但不是属性 OF Bird
函数对象,因此无法通过 Bird.hatchedEgg
访问。你看出区别了吗?
例如,运行这个代码:
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
的hatchedEgg
变量仍然无法访问了吗?它与 Ducky.hatchedEgg
.
如freecodecamp主题中所述,它称为闭包。只需使用非常琐碎的编程概念这样想:
Variables declared inside a function are scoped to that function, there is no way to access those from outside the function. This is not only true for JavaScript, for all other languages.
现在至于为什么我们可以从外部获取该作用域变量的值是闭包的魔法。由于题目没有提到"closure"这个词,更不用说问了,这里就不细说闭包了。
至于你说的黑客可以用来破解它的代码,行
Bird.hatchedEgg = 20;
仅在 对象 Bird
中创建一个 属性。这里的另一个基本概念 - 函数 Bird
也是 JavaScript 中的第一个 class 对象,这意味着它可以像任何其他对象一样具有属性和功能。 Bird.hatchedEgg
指的是Bird
对象的属性,而Bird
函数内部声明的变量(带let hatchedEgg = 10;
)是函数的局部变量,两者是截然不同的。如果该行要更改在函数内声明的局部变量的值,您应该在控制台日志中得到相同的结果 ducky.getHatchedEggCount()
,但您不会。