簡體   English   中英

javascript 中的私有成員是否安全?

[英]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 )。 這就是示例的重點,即不能從外部直接訪問私有變量。 它們是通過一種方法訪問的,而該方法又可能/不能暴露於外部。 安全感由此而來。

更新我再次重新閱讀了這個問題,你正在做的是:你將一個屬性hatchedEggBird並為其設置一個值。

Bird.hatchedEgg = 20

然而,這個hatchedEgglet 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

你明白為什么值為10hatchedEgg變量仍然無法訪問嗎? 它與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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM