亚洲国产日韩欧美一区二区三区,精品亚洲国产成人av在线,国产99视频精品免视看7,99国产精品久久久久久久成人热,欧美日韩亚洲国产综合乱

目錄
ES6 變量的誕生
使用函數(shù)
模塊設(shè)計(jì)模式
另一種方法
ES6 類
使用下劃線
將所有內(nèi)容放在構(gòu)造函數(shù)內(nèi)
使用 WeakMap
使用符號(hào)防止沖突
TC39 私有類字段提案
結(jié)論
首頁(yè) web前端 css教程 在JavaScript中實(shí)現(xiàn)私人變量

在JavaScript中實(shí)現(xiàn)私人變量

Apr 20, 2025 am 10:21 AM

Implementing Private Variables In JavaScript

JavaScript,這門賦能萬(wàn)維網(wǎng)的編程語(yǔ)言,自1995年5月由Brendan Eich創(chuàng)建以來(lái),已成為一種廣泛應(yīng)用且用途廣泛的技術(shù)。盡管它取得了成功,但它也受到了相當(dāng)多的批評(píng),尤其是一些特性。例如,對(duì)象在用作索引時(shí)被強(qiáng)制轉(zhuǎn)換為字符串形式,1 == "1" 返回 true,或者臭名昭著的令人困惑的 this 關(guān)鍵字。然而,一個(gè)特別有趣的特性是存在各種實(shí)現(xiàn)變量私有性的技術(shù)。

目前,JavaScript 中并沒有直接創(chuàng)建私有變量的方法。在其他語(yǔ)言中,您可以使用 private 關(guān)鍵字或雙下劃線,一切都能正常工作,但在 JavaScript 中,變量私有性具有使其更類似于語(yǔ)言的涌現(xiàn)特性而非預(yù)期功能的特性。讓我們先介紹一下我們問(wèn)題的背景。

var 關(guān)鍵字

在 2015 年之前,基本上只有一種創(chuàng)建變量的方法,那就是 var 關(guān)鍵字。var 是函數(shù)作用域的,這意味著用該關(guān)鍵字實(shí)例化的變量只能被函數(shù)內(nèi)的代碼訪問(wèn)。在函數(shù)外部或本質(zhì)上是“全局”的情況下,該變量將可被定義變量后執(zhí)行的任何內(nèi)容訪問(wèn)。如果您嘗試在同一作用域中訪問(wèn)變量在其定義之前,您將得到 undefined 而不是錯(cuò)誤。這是由于 var 關(guān)鍵字的“提升”方式。

// 在全局作用域中定義 "a"
var a = 123;

// 在函數(shù)作用域中定義 "b"
(function() {
  console.log(b); //=> 由于提升,返回 "undefined" 而不是錯(cuò)誤。
  var b = 456;
})();

console.log(a); // => 123
console.log(b); // 拋出 "ReferenceError" 異常,因?yàn)?"b" 無(wú)法從函數(shù)作用域外部訪問(wèn)。

ES6 變量的誕生

2015 年,ES6/ES2015 正式發(fā)布,隨之而來(lái)的是兩個(gè)新的變量關(guān)鍵字:letconst。兩者都是塊作用域的,這意味著用這些關(guān)鍵字創(chuàng)建的變量可以被同一對(duì)括號(hào)內(nèi)的任何內(nèi)容訪問(wèn)。與 var 相同,但 letconst 變量無(wú)法在循環(huán)、函數(shù)、if 語(yǔ)句、括號(hào)等塊作用域之外訪問(wèn)。

const a = 123;

// 塊作用域示例 #1
if (true) {
  const b = 345;
}

// 塊作用域示例 #2
{
  const c = 678;
}

console.log(a); // 123
console.log(b); // 拋出 "ReferenceError",因?yàn)?"b" 無(wú)法從塊作用域外部訪問(wèn)。
console.log(c); // 拋出 "ReferenceError",因?yàn)?"b" 無(wú)法從塊作用域外部訪問(wèn)。

由于作用域外部的代碼無(wú)法訪問(wèn)變量,因此我們獲得了私有性的涌現(xiàn)特性。我們將介紹一些以不同方式實(shí)現(xiàn)它的技術(shù)。

使用函數(shù)

由于 JavaScript 中的函數(shù)也是塊,因此所有變量關(guān)鍵字都與它們一起工作。此外,我們可以實(shí)現(xiàn)一個(gè)非常有用的設(shè)計(jì)模式,稱為“模塊”。

模塊設(shè)計(jì)模式

谷歌依靠牛津詞典來(lái)定義“模塊”:

程序可以從中構(gòu)建或可以分析復(fù)雜活動(dòng)的多個(gè)不同但相互關(guān)聯(lián)的單元中的任何一個(gè)。

—“模塊”定義 1.2

模塊設(shè)計(jì)模式在 JavaScript 中非常有用,因?yàn)樗Y(jié)合了公共和私有組件,并且允許我們將程序分解成更小的組件,只通過(guò)稱為“封裝”的過(guò)程公開另一個(gè)程序部分應(yīng)該能夠訪問(wèn)的內(nèi)容。通過(guò)這種方法,我們只公開需要使用的內(nèi)容,并隱藏不需要看到的內(nèi)容。我們可以利用函數(shù)作用域來(lái)實(shí)現(xiàn)這一點(diǎn)。

const CarModule = () => {
  let milesDriven = 0;
  let speed = 0;

  const accelerate = (amount) => {
    speed  = amount;
    milesDriven  = speed;
  }

  const getMilesDriven = () => milesDriven;

  // 使用 "return" 關(guān)鍵字,您可以控制哪些內(nèi)容被公開,哪些內(nèi)容被隱藏。在本例中,我們只公開 accelerate() 和 getMilesDriven() 函數(shù)。
  return {
    accelerate,
    getMilesDriven
  }
};

const testCarModule = CarModule();
testCarModule.accelerate(5);
testCarModule.accelerate(4);
console.log(testCarModule.getMilesDriven());

這樣,我們可以獲得行駛里程數(shù)以及加速度,但是由于用戶在這種情況下不需要訪問(wèn)速度,我們可以通過(guò)只公開 accelerate()getMilesDriven() 方法來(lái)隱藏它。本質(zhì)上,speed 是一個(gè)私有變量,因?yàn)樗荒鼙煌粔K作用域內(nèi)的代碼訪問(wèn)。私有變量的好處在這種情況下開始變得清晰。當(dāng)您刪除訪問(wèn)變量、函數(shù)或任何其他內(nèi)部組件的能力時(shí),您會(huì)減少因其他人錯(cuò)誤地使用本不應(yīng)使用的內(nèi)容而導(dǎo)致錯(cuò)誤的表面積。

另一種方法

在這個(gè)第二個(gè)例子中,你會(huì)注意到增加了 this 關(guān)鍵字。ES6 箭頭函數(shù)(=>)和傳統(tǒng)函數(shù)(){}之間存在差異。使用 function 關(guān)鍵字,您可以使用 this,它將綁定到函數(shù)本身,而箭頭函數(shù)不允許任何類型的 this 關(guān)鍵字的使用。兩者都是創(chuàng)建模塊的同樣有效的方法。核心思想是公開應(yīng)該訪問(wèn)的部分,并保留不應(yīng)該交互的其他部分,因此既有公共數(shù)據(jù)也有私有數(shù)據(jù)。

function CarModule() {
  let milesDriven = 0;
  let speed = 0;

  // 在這種情況下,我們改為使用 "this" 關(guān)鍵字,
  // 它指的是 CarModule
  this.accelerate = (amount) => {
    speed  = amount;
    milesDriven  = speed;
  }

  this.getMilesDriven = () => milesDriven;
}

const testCarModule = new CarModule();
testCarModule.accelerate(5);
testCarModule.accelerate(4);
console.log(testCarModule.getMilesDriven());

ES6 類

類是 ES6 中的另一個(gè)新增功能。類本質(zhì)上是語(yǔ)法糖——換句話說(shuō),仍然是一個(gè)函數(shù),但可能會(huì)將其“美化”成更容易表達(dá)的形式。對(duì)于類,變量私有性(截至目前)幾乎是不可能的,除非對(duì)代碼進(jìn)行一些重大更改。

讓我們來(lái)看一個(gè)類示例。

class CarModule {
  /*
    milesDriven = 0;
    speed = 0;
  */
  constructor() {
    this.milesDriven = 0;
    this.speed = 0;
  }
  accelerate(amount) {
    this.speed  = amount;
    this.milesDriven  = this.speed;
  }
  getMilesDriven() {
    return this.milesDriven;
  }
}

const testCarModule = new CarModule();
testCarModule.accelerate(5);
testCarModule.accelerate(4);
console.log(testCarModule.getMilesDriven());

首先要注意的是,milesDrivenspeed 變量位于 constructor() 函數(shù)內(nèi)。請(qǐng)注意,您也可以在構(gòu)造函數(shù)之外定義變量(如代碼注釋所示),但無(wú)論如何它們?cè)诠δ苌隙际窍嗤?。?wèn)題是這些變量將是公共的,并且可以被類外部的元素訪問(wèn)。

讓我們看看解決這個(gè)問(wèn)題的一些方法。

使用下劃線

在私有性是為了防止協(xié)作者犯一些災(zāi)難性錯(cuò)誤的情況下,用下劃線(_)作為變量前綴,盡管仍然對(duì)外部“可見”,但足以向開發(fā)人員發(fā)出信號(hào),“不要碰這個(gè)變量”。因此,例如,我們現(xiàn)在有以下內(nèi)容:

// 這是類的新的構(gòu)造函數(shù)。請(qǐng)注意,它也可以表示為構(gòu)造函數(shù)()之外的以下內(nèi)容。
/*
  _milesDriven = 0;
  _speed = 0;
*/
constructor() {
  this._milesDriven = 0;
  this._speed = 0;
}

雖然這對(duì)于它的特定用例有效,但仍然可以肯定地說(shuō),它在許多方面都不理想。您仍然可以訪問(wèn)變量,但您還必須修改變量名稱。

將所有內(nèi)容放在構(gòu)造函數(shù)內(nèi)

從技術(shù)上講,確實(shí)有一種方法可以在類中使用私有變量,那就是將所有變量和方法放在 constructor() 函數(shù)內(nèi)。讓我們來(lái)看一下。

class CarModule {
  constructor() {
    let milesDriven = 0;
    let speed = 0;

    this.accelerate = (amount) => {
      speed  = amount;
      milesDriven  = speed;
    }

    this.getMilesDriven = () => milesDriven;
  }
}

const testCarModule = new CarModule();
testCarModule.accelerate(5);
testCarModule.accelerate(4);
console.log(testCarModule.getMilesDriven());
console.log(testCarModule.speed); // undefined -- 我們現(xiàn)在有了真正的變量私有性。

這種方法實(shí)現(xiàn)了真正的變量私有性,因?yàn)闊o(wú)法直接訪問(wèn)未故意公開的任何變量。問(wèn)題是我們現(xiàn)在有了,嗯,與我們之前相比,看起來(lái)不太好的代碼,此外它還破壞了我們使用類時(shí)語(yǔ)法糖的好處。此時(shí),我們不妨使用 function() 方法。

使用 WeakMap

還有一種更具創(chuàng)造性的方法來(lái)創(chuàng)建私有變量,那就是使用 WeakMap()。雖然它可能聽起來(lái)類似于 Map,但兩者非常不同。雖然映射可以將任何類型的值作為鍵,但 WeakMap 只接受對(duì)象并在垃圾收集對(duì)象鍵時(shí)刪除 WeakMap 中的值。此外,WeakMap 無(wú)法迭代,這意味著您必須訪問(wèn)對(duì)對(duì)象鍵的引用才能訪問(wèn)值。這使得它對(duì)于創(chuàng)建私有變量非常有用,因?yàn)樽兞繉?shí)際上是不可見的。

class CarModule {
  constructor() {
    this.data = new WeakMap();
    this.data.set(this, {
      milesDriven: 0,
      speed: 0
    });
    this.getMilesDriven = () => this.data.get(this).milesDriven;
  }

  accelerate(amount) {
    // 在這個(gè)版本中,我們改為創(chuàng)建一個(gè) WeakMap 并
    // 使用 "this" 關(guān)鍵字作為鍵,這不太可能
    // 被意外地用作 WeakMap 的鍵。
    const data = this.data.get(this);
    const speed = data.speed   amount;
    const milesDriven = data.milesDriven   data.speed;
    this.data.set({ speed, milesDriven });
  }

}

const testCarModule = new CarModule();
testCarModule.accelerate(5);
testCarModule.accelerate(4);
console.log(testCarModule.getMilesDriven());
console.log(testCarModule.data); //=> WeakMap { [items unknown] } -- 此數(shù)據(jù)無(wú)法從外部輕松訪問(wèn)!

此解決方案擅長(zhǎng)防止意外使用數(shù)據(jù),但它并非真正私有,因?yàn)樗匀豢梢酝ㄟ^(guò)用 CarModule 替換 this 從外部訪問(wèn)。此外,它增加了相當(dāng)多的復(fù)雜性,因此并不是最優(yōu)雅的解決方案。

使用符號(hào)防止沖突

如果目的是防止名稱沖突,則可以使用 Symbol 提供一個(gè)有用的解決方案。這些本質(zhì)上是可以作為唯一值行為的實(shí)例,它們永遠(yuǎn)不會(huì)等于任何其他值,除了它自己的唯一實(shí)例。以下是它在實(shí)際應(yīng)用中的示例:

class CarModule {
  constructor() {
    this.speedKey = Symbol("speedKey");
    this.milesDrivenKey = Symbol("milesDrivenKey");
    this[this.speedKey] = 0;
    this[this.milesDrivenKey] = 0;
  }

  accelerate(amount) {
    // 此數(shù)據(jù)幾乎不可能被意外訪問(wèn)。它決不是私有的,
    // 但它遠(yuǎn)離任何將要實(shí)現(xiàn)此模塊的人。
    this[this.speedKey]  = amount;
    this[this.milesDrivenKey]  = this[this.speedKey];
  }

  getMilesDriven() {
    return this[this.milesDrivenKey];
  }
}

const testCarModule = new CarModule();
testCarModule.accelerate(5);
testCarModule.accelerate(4);
console.log(testCarModule.getMilesDriven());
console.log(testCarModule.speed); // => undefined -- 我們需要訪問(wèn)內(nèi)部鍵才能訪問(wèn)變量。

與下劃線解決方案一樣,此方法或多或少依賴于命名約定來(lái)防止混淆。

TC39 私有類字段提案

最近,提出了一項(xiàng)新的提案,該提案將向類引入私有變量。它很簡(jiǎn)單:在變量名稱前加上 #,它就變成私有的。無(wú)需額外的結(jié)構(gòu)更改。

class CarModule {
  #speed = 0
  #milesDriven = 0

  accelerate(amount) {
    // 此數(shù)據(jù)幾乎不可能被意外訪問(wèn)。
    this.#speed  = amount;
    this.#milesDriven  = speed;
  }

  getMilesDriven() {
    return this.#milesDriven;
  }
}

const testCarModule = new CarModule();
testCarModule.accelerate(5);
testCarModule.accelerate(4);
console.log(testCarModule.getMilesDriven());
console.log(testCarModule.speed); //=> undefined -- 我們需要訪問(wèn)內(nèi)部鍵才能訪問(wèn)變量。

私有類特性已經(jīng)成為現(xiàn)實(shí),并且已經(jīng)擁有相當(dāng)好的瀏覽器支持。

結(jié)論

這就是在 JavaScript 中實(shí)現(xiàn)私有變量的各種方法的總結(jié)。沒有一種“正確”的方法。這些方法適用于不同的需求、現(xiàn)有代碼庫(kù)和其他約束。雖然每種方法都有其優(yōu)點(diǎn)和缺點(diǎn),但最終,只要它們有效地解決了您的問(wèn)題,所有方法都是同樣有效的。

感謝您的閱讀!我希望這能為您提供一些關(guān)于如何應(yīng)用作用域和變量私有性來(lái)改進(jìn)您的 JavaScript 代碼的見解。這是一種強(qiáng)大的技術(shù),可以支持許多不同的方法,并使您的代碼更易于使用且無(wú)錯(cuò)誤。自己嘗試一些新示例,獲得更好的感覺。

以上是在JavaScript中實(shí)現(xiàn)私人變量的詳細(xì)內(nèi)容。更多信息請(qǐng)關(guān)注PHP中文網(wǎng)其他相關(guān)文章!

本站聲明
本文內(nèi)容由網(wǎng)友自發(fā)貢獻(xiàn),版權(quán)歸原作者所有,本站不承擔(dān)相應(yīng)法律責(zé)任。如您發(fā)現(xiàn)有涉嫌抄襲侵權(quán)的內(nèi)容,請(qǐng)聯(lián)系admin@php.cn

熱AI工具

Undress AI Tool

Undress AI Tool

免費(fèi)脫衣服圖片

Undresser.AI Undress

Undresser.AI Undress

人工智能驅(qū)動(dòng)的應(yīng)用程序,用于創(chuàng)建逼真的裸體照片

AI Clothes Remover

AI Clothes Remover

用于從照片中去除衣服的在線人工智能工具。

Clothoff.io

Clothoff.io

AI脫衣機(jī)

Video Face Swap

Video Face Swap

使用我們完全免費(fèi)的人工智能換臉工具輕松在任何視頻中換臉!

熱工具

記事本++7.3.1

記事本++7.3.1

好用且免費(fèi)的代碼編輯器

SublimeText3漢化版

SublimeText3漢化版

中文版,非常好用

禪工作室 13.0.1

禪工作室 13.0.1

功能強(qiáng)大的PHP集成開發(fā)環(huán)境

Dreamweaver CS6

Dreamweaver CS6

視覺化網(wǎng)頁(yè)開發(fā)工具

SublimeText3 Mac版

SublimeText3 Mac版

神級(jí)代碼編輯軟件(SublimeText3)

熱門話題

Laravel 教程
1597
29
PHP教程
1488
72
CSS教程,用于創(chuàng)建加載旋轉(zhuǎn)器和動(dòng)畫 CSS教程,用于創(chuàng)建加載旋轉(zhuǎn)器和動(dòng)畫 Jul 07, 2025 am 12:07 AM

創(chuàng)建CSS加載旋轉(zhuǎn)器的方法有三種:1.使用邊框的基本旋轉(zhuǎn)器,通過(guò)HTML和CSS實(shí)現(xiàn)簡(jiǎn)單動(dòng)畫;2.使用多個(gè)點(diǎn)的自定義旋轉(zhuǎn)器,通過(guò)不同延遲時(shí)間實(shí)現(xiàn)跳動(dòng)效果;3.在按鈕中添加旋轉(zhuǎn)器,通過(guò)JavaScript切換類來(lái)顯示加載狀態(tài)。每種方法都強(qiáng)調(diào)了設(shè)計(jì)細(xì)節(jié)如顏色、大小、可訪問(wèn)性和性能優(yōu)化的重要性,以提升用戶體驗(yàn)。

解決CSS瀏覽器兼容性問(wèn)題和前綴 解決CSS瀏覽器兼容性問(wèn)題和前綴 Jul 07, 2025 am 01:44 AM

處理CSS瀏覽器兼容性和前綴問(wèn)題需理解瀏覽器支持差異并合理使用廠商前綴。1.了解常見問(wèn)題如Flexbox、Grid支持不一,position:sticky失效,動(dòng)畫表現(xiàn)不同;2.查閱CanIuse確認(rèn)特性支持情況;3.正確使用-webkit-、-moz-、-ms-、-o-等廠商前綴;4.推薦使用Autoprefixer自動(dòng)添加前綴;5.安裝PostCSS并配置browserslist指定目標(biāo)瀏覽器;6.構(gòu)建時(shí)自動(dòng)處理兼容性;7.老項(xiàng)目可用Modernizr檢測(cè)特性;8.不必追求所有瀏覽器一致,確

使用CSS剪輯路徑創(chuàng)建自定義形狀 使用CSS剪輯路徑創(chuàng)建自定義形狀 Jul 09, 2025 am 01:29 AM

使用CSS的clip-path屬性可以裁剪元素為自定義形狀,如三角形、圓形缺口、多邊形等,無(wú)需依賴圖片或SVG。其優(yōu)勢(shì)包括:1.支持circle、ellipse、polygon等多種基本形狀;2.可響應(yīng)式調(diào)整,適配移動(dòng)端;3.易于動(dòng)畫化,可結(jié)合hover或JavaScript實(shí)現(xiàn)動(dòng)態(tài)效果;4.不影響布局流,僅裁剪顯示區(qū)域。常見用法如圓形裁剪clip-path:circle(50pxatcenter)和三角形裁剪clip-path:polygon(50%0%,1000%,00%)。注意

顯示:內(nèi)聯(lián),顯示:塊和顯示:內(nèi)聯(lián)塊之間有什么區(qū)別? 顯示:內(nèi)聯(lián),顯示:塊和顯示:內(nèi)聯(lián)塊之間有什么區(qū)別? Jul 11, 2025 am 03:25 AM

Themaindifferencesbetweendisplay:inline,block,andinline-blockinHTML/CSSarelayoutbehavior,spaceusage,andstylingcontrol.1.Inlineelementsflowwithtext,don’tstartonnewlines,ignorewidth/height,andonlyapplyhorizo??ntalpadding/margins—idealforinlinetextstyling

造型與CSS不同訪問(wèn)的鏈接 造型與CSS不同訪問(wèn)的鏈接 Jul 11, 2025 am 03:26 AM

設(shè)置訪問(wèn)過(guò)鏈接的樣式能提升用戶體驗(yàn),尤其在內(nèi)容密集型網(wǎng)站中幫助用戶更好導(dǎo)航。1.使用CSS的:visited偽類可定義已訪問(wèn)鏈接樣式,如顏色變化;2.注意瀏覽器出于隱私限制僅允許修改部分屬性;3.顏色選擇應(yīng)與整體風(fēng)格協(xié)調(diào),避免突兀;4.移動(dòng)端可能不顯示該效果,建議結(jié)合其他視覺提示如icon輔助標(biāo)識(shí)。

如何使用CSS創(chuàng)建響應(yīng)式圖像? 如何使用CSS創(chuàng)建響應(yīng)式圖像? Jul 15, 2025 am 01:10 AM

要使用CSS創(chuàng)建響應(yīng)式圖片,主要可通過(guò)以下方法實(shí)現(xiàn):1.使用max-width:100%和height:auto讓圖片在保持比例的同時(shí)自適應(yīng)容器寬度;2.結(jié)合HTML的srcset和sizes屬性智能加載適配不同屏幕的圖片源;3.利用object-fit和object-position控制圖片裁剪與焦點(diǎn)展示。這些方法共同確保圖片在不同設(shè)備上清晰、美觀地呈現(xiàn)。

揭開CSS單元的神秘面紗:PX,EM,REM,VW,VH比較 揭開CSS單元的神秘面紗:PX,EM,REM,VW,VH比較 Jul 08, 2025 am 02:16 AM

CSS單位的選擇取決于設(shè)計(jì)需求和響應(yīng)式要求。1.px用于固定尺寸,適合精確控制但缺乏彈性;2.em是相對(duì)單位,受父元素影響易導(dǎo)致級(jí)聯(lián)問(wèn)題,rem則基于根元素更穩(wěn)定,適合全局縮放;3.vw/vh基于視口大小,適合響應(yīng)式設(shè)計(jì),但需注意極端屏幕下的表現(xiàn);4.選擇時(shí)應(yīng)根據(jù)是否需要響應(yīng)式調(diào)整、元素層級(jí)關(guān)系及視口依賴程度來(lái)決定,合理搭配使用可提升布局靈活性與維護(hù)性。

什么是常見的CSS瀏覽器不一致? 什么是常見的CSS瀏覽器不一致? Jul 26, 2025 am 07:04 AM

不同瀏覽器對(duì)CSS解析存在差異,導(dǎo)致顯示效果不一致,主要包括默認(rèn)樣式差異、盒模型計(jì)算方式、Flexbox和Grid布局支持程度及某些CSS屬性行為不一致。1.默認(rèn)樣式處理不一致,解決方法是使用CSSReset或Normalize.css統(tǒng)一初始樣式;2.舊版IE的盒模型計(jì)算方式不同,建議統(tǒng)一使用box-sizing:border-box;3.Flexbox和Grid在邊緣情況或舊版本中表現(xiàn)有差異,應(yīng)多測(cè)試并使用Autoprefixer;4.某些CSS屬性行為不一致,需查閱CanIuse并提供降級(jí)

See all articles