[英]Is a private member secure in javascript?
我正在關注freecodecamp JavaScript oop 課程。 本課程描述了如何在對象內部聲明一個私有變量,用於無法從外部更改的密碼和銀行賬戶等情況。 對私有變量的唯一訪問是通過可以訪問私有變量的公共方法。 然后它給出了這個演示代碼來說明這一點。
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 變量如何被稱為安全的。 作為用戶/黑客,我所要做的就是猜測從 function getHatchedEggCount() 返回的變量名。 在這種情況下,hatchedEgg(這對黑客來說並不太難),然后我可以使用這一行來修改私有變量;
Bird.hatchedEgg = 20;
console.log(Bird) // returns { [Function: Bird] hatchedEgg : 20 }
我錯過了什么嗎?
//-------------- Clarification Edit
顯然問題出在 freecodecamp 控制台(A Bug)上,它正在更改私有變量的值。 如果你願意,你可以嘗試在這個鏈接中粘貼上面的代碼,你會看到。 freecodeConsoleLink
直接調用ducky.hatchedEgg
(我猜你的意思是這個而不是Bird.hatchedEgg
)不會給你任何結果(准確地說是undefined
)。 這就是示例的重點,即不能從外部直接訪問私有變量。 它們是通過一種方法訪問的,而該方法又可能/不能暴露於外部。 安全感由此而來。
更新我再次重新閱讀了這個問題,你正在做的是:你將一個屬性hatchedEgg
到Bird
並為其設置一個值。
Bird.hatchedEgg = 20
然而,這個hatchedEgg
和let hatchedEgg = 10;
最初在 function 中定義。
ducky.getHatchedEggCount();
仍然會給你 10。 Bird.hatchedEgg
會給你20
,因為你將屬性hatchedEgg
到 object Bird
與在 function Bird
中聲明的hatchedEgg
不同。
此外, function
是一流的 object,您可以像使用任何其他 object 一樣向其添加/刪除屬性。 但是,在上一篇文章中,我有意將function
Bird 和object
Bird 區分開來,以說明問題。 就像說, array
也是objects
。 但是你在談話中保持一種區分,以便把事情簡單化。 無論如何,我認為更新它會導致某種混亂。
我認為您對正在創建的變量以及如何訪問每個變量感到有些困惑。
您從 function 開始:
function Bird() {
let hatchedEgg = 10;
this.getHatchedEggCount = function () {
return hatchedEgg;
};
}
這個 function 沒有任何屬性。
當調用此 function 時,它只是將getHatchedEggCount
屬性附加this
object。 getHatchedEggCount
屬性本身就是一個 function,它引用Bird
function 運行時創建的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();
和控制台日志記錄提供以下 output:
console.log(ducky);
// Output: Bird { getHatchedEggCount: [Function] }
console.log(ducky.hatchedEgg);
// Output: undefined
console.log(ducky.getHatchedEggCount());
// Output: 10
這一切都在意料之中,因為ducky
是一個object,只有一個屬性getHatchedEggCount
方法。
但最重要的是,請注意當我們記錄以下內容時會發生什么:
console.log(Bird);
// Output: [Function: Bird]
console.log(Bird.hatchedEgg);
// Output: undefined
console.log(Bird.getHatchedEggCount);
// Output: undefined
我們看到Bird
function實際上是一個空的object。 它沒有屬性(我們自己分配的),因此Bird.hatchedEgg
不存在!
那么,為什么我們可以在調用
ducky.getHatchedEggCount()
時訪問hatchedEgg
變量呢? 這是由於閉包是如何工作的,但這是題外話。 不用說,hatchedEgg
變量只能由getHatchedEggCount
function 訪問。
現在,如果我們說:
Bird.hatchedEgg = 20;
我們正在為Bird
function 添加一個全新的屬性。 所以我們可以控制台日志:
console.log(Bird);
// Output: [Function: Bird] { hatchedEgg: 20 }
console.log(Bird.hatchedEgg);
// Output: 20
我們為Bird
function 添加了一個新的hatchedEgg
屬性,這是以前不存在的!
但是請注意,這與getHatchedEggCount
function 使用的hatchedEgg
變量的屬性不同。
The original hatchedEgg
variable is created inside the Bird
function and is accessible inside the function body, but is not a property OF the Bird
function object, therefore not accessible by doing 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 主題中所述,它被稱為閉包。 只需使用非常瑣碎的編程概念來這樣想:
在 function 中聲明的變量的范圍是 function,無法從 function 外部訪問這些變量。 這不僅適用於 JavaScript,適用於所有其他語言。
現在,為什么我們可以從外部獲取該作用域變量的值,這就是閉包的魔力。 由於問題沒有提到“關閉”這個詞,更不用說詢問它了,我不會 go 在這里詳細介紹關閉。
至於你說黑客可以用來破解它的代碼,這條線
Bird.hatchedEgg = 20;
僅在object Bird
內創建一個屬性。 Another basic concept here - the function Bird
is also a first class object in JavaScript, meaning it can have properties as well as functions just like any other objects. Bird.hatchedEgg
指的是Bird
object 的屬性,而Bird
function 內部聲明的變量(其中let hatchedEgg = 10;
)是 ZC1C425268E68385D1AB4Z5074 的局部變量。 如果該行要更改在 function 中聲明的局部變量的值,則在控制台日志中應該會得到相同的結果ducky.getHatchedEggCount()
,但不會。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.