国产av日韩一区二区三区精品,成人性爱视频在线观看,国产,欧美,日韩,一区,www.成色av久久成人,2222eeee成人天堂

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

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

Apr 20, 2025 am 10:21 AM

Implementing Private Variables In JavaScript

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

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

var關(guān)鍵字

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

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

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

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

ES6 變量的誕生

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

 const a = 123;

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

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

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

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

使用函數(shù)

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

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

谷歌依靠牛津詞典來定義“模塊”:

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

—“模塊”定義1.2

模塊設(shè)計(jì)模式在JavaScript 中非常有用,因?yàn)樗Y(jié)合了公共和私有組件,並且允許我們將程序分解成更小的組件,只通過稱為“封裝”的過程公開另一個程序部分應(yīng)該能夠訪問的內(nèi)容。通過這種方法,我們隻公開需要使用的內(nèi)容,並隱藏不需要看到的內(nèi)容。我們可以利用函數(shù)作用域來實(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ù)以及加速度,但是由於用戶在這種情況下不需要訪問速度,我們可以通過隻公開accelerate()getMilesDriven()方法來隱藏它。本質(zhì)上, speed是一個私有變量,因?yàn)樗荒鼙煌粔K作用域內(nèi)的代碼訪問。私有變量的好處在這種情況下開始變得清晰。當(dāng)您刪除訪問變量、函數(shù)或任何其他內(nèi)部組件的能力時(shí),您會減少因其他人錯誤地使用本不應(yīng)使用的內(nèi)容而導(dǎo)致錯誤的表面積。

另一種方法

在這個第二個例子中,你會注意到增加了this關(guān)鍵字。 ES6 箭頭函數(shù)(=>)和傳統(tǒng)函數(shù)(){}之間存在差異。使用function關(guān)鍵字,您可以使用this ,它將綁定到函數(shù)本身,而箭頭函數(shù)不允許任何類型的this關(guān)鍵字的使用。兩者都是創(chuàng)建模塊的同樣有效的方法。核心思想是公開應(yīng)該訪問的部分,並保留不應(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 中的另一個新增功能。類本質(zhì)上是語法糖——換句話說,仍然是一個函數(shù),但可能會將其“美化”成更容易表達(dá)的形式。對於類,變量私有性(截至目前)幾乎是不可能的,除非對代碼進(jìn)行一些重大更改。

讓我們來看一個類示例。

 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)。請注意,您也可以在構(gòu)造函數(shù)之外定義變量(如代碼註釋所示),但無論如何它們在功能上都是相同的。問題是這些變量將是公共的,並且可以被類外部的元素訪問。

讓我們看看解決這個問題的一些方法。

使用下劃線

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

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

雖然這對於它的特定用例有效,但仍然可以肯定地說,它在許多方面都不理想。您仍然可以訪問變量,但您還必須修改變量名稱。

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

從技術(shù)上講,確實(shí)有一種方法可以在類中使用私有變量,那就是將所有變量和方法放在constructor()函數(shù)內(nè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法直接訪問未故意公開的任何變量。問題是我們現(xiàn)在有了,嗯,與我們之前相比,看起來不太好的代碼,此外它還破壞了我們使用類時(shí)語法糖的好處。此時(shí),我們不妨使用function()方法。

使用WeakMap

還有一種更具創(chuàng)造性的方法來創(chuàng)建私有變量,那就是使用WeakMap() 。雖然它可能聽起來類似於Map ,但兩者非常不同。雖然映射可以將任何類型的值作為鍵,但WeakMap只接受對象並在垃圾收集對象鍵時(shí)刪除WeakMap中的值。此外, WeakMap無法迭代,這意味著您必須訪問對對象鍵的引用才能訪問值。這使得它對於創(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) {
    // 在這個版本中,我們改為創(chuàng)建一個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ù)無法從外部輕鬆訪問!

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

使用符號防止衝突

如果目的是防止名稱衝突,則可以使用Symbol提供一個有用的解決方案。這些本質(zhì)上是可以作為唯一值行為的實(shí)例,它們永遠(yuǎn)不會等於任何其他值,除了它自己的唯一實(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ù)幾乎不可能被意外訪問。它決不是私有的,
    // 但它遠(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 -- 我們需要訪問內(nèi)部鍵才能訪問變量。

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

TC39 私有類字段提案

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

 class CarModule {
  #speed = 0
  #milesDriven = 0

  accelerate(amount) {
    // 此數(shù)據(jù)幾乎不可能被意外訪問。
    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 -- 我們需要訪問內(nèi)部鍵才能訪問變量。

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

結(jié)論

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

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

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

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

熱AI工具

Undress AI Tool

Undress AI Tool

免費(fèi)脫衣圖片

Undresser.AI Undress

Undresser.AI Undress

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

AI Clothes Remover

AI Clothes Remover

用於從照片中去除衣服的線上人工智慧工具。

Clothoff.io

Clothoff.io

AI脫衣器

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)頁開發(fā)工具

SublimeText3 Mac版

SublimeText3 Mac版

神級程式碼編輯軟體(SublimeText3)

什麼是'渲染障礙CSS”? 什麼是'渲染障礙CSS”? Jun 24, 2025 am 12:42 AM

CSS會阻塞頁面渲染是因?yàn)闉g覽器默認(rèn)將內(nèi)聯(lián)和外部CSS視為關(guān)鍵資源,尤其是使用引入的樣式表、頭部大量內(nèi)聯(lián)CSS以及未優(yōu)化的媒體查詢樣式。 1.提取關(guān)鍵CSS並內(nèi)嵌至HTML;2.延遲加載非關(guān)鍵CSS通過JavaScript;3.使用media屬性優(yōu)化加載如打印樣式;4.壓縮合併CSS減少請求。建議使用工具提取關(guān)鍵CSS,結(jié)合rel="preload"異步加載,合理使用media延遲加載,避免過度拆分與復(fù)雜腳本控制。

什麼是AutoPrefixer,它如何工作? 什麼是AutoPrefixer,它如何工作? Jul 02, 2025 am 01:15 AM

Autoprefixer是一個根據(jù)目標(biāo)瀏覽器範(fàn)圍自動為CSS屬性添加廠商前綴的工具。 1.它解決了手動維護(hù)前綴易出錯的問題;2.通過PostCSS插件形式工作,解析CSS、分析需加前綴的屬性、依配置生成代碼;3.使用步驟包括安裝插件、設(shè)置browserslist、在構(gòu)建流程中啟用;4.注意事項(xiàng)有不手動加前綴、保持配置更新、非所有屬性都加前綴、建議配合預(yù)處理器使用。

什麼是圓錐級函數(shù)? 什麼是圓錐級函數(shù)? Jul 01, 2025 am 01:16 AM

theconic-Gradient()functionIncsscreatesCircularGradientsThatRotateColorStopSaroundAcentralPoint.1.IsidealForPieCharts,ProgressIndicators,colordichers,colorwheels和decorativeBackgrounds.2.itworksbysbysbysbydefindefingincolordefingincolorstopsatspecificains off.

CSS教程,用於創(chuàng)建粘性標(biāo)頭或頁腳 CSS教程,用於創(chuàng)建粘性標(biāo)頭或頁腳 Jul 02, 2025 am 01:04 AM

TocreatestickyheadersandfooterswithCSS,useposition:stickyforheaderswithtopvalueandz-index,ensuringparentcontainersdon’trestrictit.1.Forstickyheaders:setposition:sticky,top:0,z-index,andbackgroundcolor.2.Forstickyfooters,betteruseposition:fixedwithbot

CSS自定義屬性的範(fàn)圍是什麼? CSS自定義屬性的範(fàn)圍是什麼? Jun 25, 2025 am 12:16 AM

CSS自定義屬性的作用域取決於其聲明的上下文,全局變量通常定義在:root中,而局部變量則定義在特定選擇器內(nèi),以便組件化和隔離樣式。例如,定義在.card類中的變量僅對匹配該類的元素及其子元素可用。最佳實(shí)踐包括:1.使用:root定義全局變量如主題色;2.在組件內(nèi)部定義局部變量以實(shí)現(xiàn)封裝;3.避免重複聲明同一變量;4.注意選擇器特異性可能引發(fā)的覆蓋問題。此外,CSS變量區(qū)分大小寫,且應(yīng)在使用前定義以避免錯誤。若變量未定義或引用失敗,則會採用回退值或默認(rèn)值initial。調(diào)試時(shí)可通過瀏覽器開發(fā)者工

CSS教程專注於移動優(yōu)先設(shè)計(jì) CSS教程專注於移動優(yōu)先設(shè)計(jì) Jul 02, 2025 am 12:52 AM

Mobile-firstCSSdesignrequiressettingtheviewportmetatag,usingrelativeunits,stylingfromsmallscreensup,optimizingtypographyandtouchtargets.First,addtocontrolscaling.Second,use%,em,orreminsteadofpixelsforflexiblelayouts.Third,writebasestylesformobile,the

CSS教程,用於創(chuàng)建加載旋轉(zhuǎn)器和動畫 CSS教程,用於創(chuàng)建加載旋轉(zhuǎn)器和動畫 Jul 07, 2025 am 12:07 AM

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

如何創(chuàng)建本質(zhì)上響應(yīng)的網(wǎng)格佈局? 如何創(chuàng)建本質(zhì)上響應(yīng)的網(wǎng)格佈局? Jul 02, 2025 am 01:19 AM

要創(chuàng)建內(nèi)在響應(yīng)式網(wǎng)格佈局,核心方法是使用CSSGrid的repeat(auto-fit,minmax())模式;1.設(shè)置grid-template-columns:repeat(auto-fit,minmax(200px,1fr))讓瀏覽器自動調(diào)整列數(shù)並限制每列最小和最大寬度;2.使用gap控制格子間距;3.容器應(yīng)設(shè)為相對單位如width:100%、配合box-sizing:border-box避免寬度計(jì)算錯誤並用margin:auto居中;4.可選設(shè)置行高與內(nèi)容對齊方式提升視覺一致性,如row

See all articles