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

Table of Contents
var keyword
The birth of ES6 variables
Using functions
Module design mode
Another way
ES6 Class
Use underline
Put everything in the constructor
Using WeakMap
Use symbols to prevent conflict
TC39 Private Class Field Proposal
in conclusion
Home Web Front-end CSS Tutorial Implementing Private Variables In JavaScript

Implementing Private Variables In JavaScript

Apr 20, 2025 am 10:21 AM

Implementing Private Variables In JavaScript

JavaScript, the programming language that empowers the World Wide Web, has become a widely used and versatile technology since its creation by Brendan Eich in May 1995. Despite its success, it has also received considerable criticism, especially some features. For example, an object is cast to a string when used as an index, 1 == "1" returns true, or the infamous confusing this keyword. However, one particularly interesting feature is the existence of various techniques that implement variable privacy.

Currently, there is no way to directly create private variables in JavaScript. In other languages, you can use private keywords or double underscores and everything works fine, but in JavaScript, variable privateness has features that make it more similar to the emergent features of the language than the expected functionality. Let's first introduce the background of our question.

var keyword

Until 2015, there was basically only one way to create variables, and that was the var keyword. var is function scoped, which means that variables instantiated with this keyword can only be accessed by code within the function. In the case where the function is external or essentially "global", the variable will be accessible by anything executed after the variable is defined. If you try to access the variable in the same scope before its definition, you will get undefined instead of an error. This is due to the "upgrade" way of the var keyword.

 // Define "a" in global scope
var a = 123;

// Define "b" in function scope
(function() {
  console.log(b); //=> Due to promotion, "undefined" is returned instead of an error.
  var b = 456;
})();

console.log(a); // => 123
console.log(b); // Throws a "ReferenceError" exception because "b" cannot be accessed from outside the function scope.

The birth of ES6 variables

In 2015, ES6/ES2015 was officially released, and followed by two new variable keywords: let and const . Both are block-scoped, meaning that variables created with these keywords can be accessed by anything within the same pair of brackets. Same as var , but let and const variables cannot be accessed outside block scopes such as loops, functions, if statements, brackets, etc.

 const a = 123;

// Block Scope Example #1
if (true) {
  const b = 345;
}

// Block Scope Example #2
{
  const c = 678;
}

console.log(a); // 123
console.log(b); // Throws "ReferenceError" because "b" cannot be accessed from outside the block scope.
console.log(c); // Throws "ReferenceError" because "b" cannot be accessed from outside the block scope.

Since code outside the scope cannot access variables, we obtain the emergence of privateness. We will introduce some techniques to implement it in different ways.

Using functions

Since functions in JavaScript are also blocks, all variable keywords work with them. Furthermore, we can implement a very useful design pattern called "module".

Module design mode

Google relies on the Oxford Dictionary to define "modules":

The program may construct from it or may analyze any of a number of different but interrelated units of complex activities.

— “Module” definition 1.2

The module design pattern is very useful in JavaScript because it combines public and private components and allows us to break down programs into smaller components, exposing only what another program part should be able to access through a process called "encapsulation". In this way, we only expose what we need to use and hide what we don’t need to see. We can do this by leveraging the function scope.

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

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

  const getMilesDriven = () => milesDriven;

  // Using the "return" keyword, you can control what content is exposed and what content is hidden. In this case, we expose only the accelerate() and getMilesDriven() functions.
  return {
    accelerate,
    getMilesDriven
  }
};

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

This way we can get mileage and acceleration, but since the user does not need access speed in this case, we can hide it by exposing only accelerate() and getMilesDriven() methods. Essentially, speed is a private variable because it can only be accessed by code within the same scope. The benefits of private variables start to become clear in this case. When you delete the ability to access variables, functions, or any other internal components, you reduce the surface area that is wrongly used by others by mistake by others that should not have been used.

Another way

In this second example, you will notice the addition of this keyword. There is a difference between the ES6 arrow function (=>) and the traditional function (){}. With function keyword you can use this , which will bind to the function itself, and the arrow function does not allow the use of any type of this keyword. Both are equally effective ways to create modules. The core idea is to disclose the parts that should be accessed and retain other parts that should not be interacted with, so there is both public and private data.

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

  // In this case, we use the "this" keyword instead,
  // It refers to 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 Class

Classes are another new feature in ES6. Classes are essentially syntactic sugar—in other words, still a function, but may "beautify" it into a more easily expressed form. For classes, variable privateness (as of now) is nearly impossible unless some major changes are made to the code.

Let's look at an example of a class.

 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());

The first thing to note is that milesDriven and speed variables are located in constructor() function. Note that you can also define variables outside of the constructor (as shown in the code comments), but they are functionally the same anyway. The problem is that these variables will be public and can be accessed by elements outside the class.

Let's take a look at some solutions to this problem.

Use underline

In situations where privateness is to prevent collaborators from making some catastrophic mistakes, using an underscore (_) as a variable prefix, although it is still "visible" to the outside, is enough to signal the developer, "Don't touch this variable". So, for example, we now have the following:

 // This is the new constructor of the class. Note that it can also be represented as the following content outside the constructor().
/*
  _milesDriven = 0;
  _speed = 0;
*/
constructor() {
  this._milesDriven = 0;
  this._speed = 0;
}

While this works for its specific use cases, it is still safe to say that it is not ideal in many ways. You can still access the variables, but you also have to modify the variable name.

Put everything in the constructor

Technically, there is indeed a way to use private variables in a class, which is to put all variables and methods in constructor() function. Let's take a look.

 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 -- We now have real variable privacy.

This approach implements true variable privacy because there is no direct access to any variable that is not intentionally disclosed. The problem is that we have now, well, not looking very good code compared to ours, and it also breaks the benefits of syntax sugar when we use classes. At this time, we might as well use function() method.

Using WeakMap

There is also a more creative way to create private variables, which is to use WeakMap() . While it may sound similar to Map , the two are very different. While the mapping can take any type of value as a key, WeakMap only accepts objects and deletes the values ??in WeakMap when garbage collects object keys. Additionally, WeakMap cannot iterate, meaning you have to access a reference to the object key to access the value. This makes it very useful for creating private variables, because variables are actually invisible.

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

  accelerate(amount) {
    // In this version, we instead create a WeakMap and // use the "this" keyword as the key, which is unlikely // will be accidentally used as the key for the 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] } -- This data cannot be easily accessed from the outside!

This solution is good at preventing accidental use of data, but it is not really private, as it can still be accessed from outside by replacing this with CarModule . Furthermore, it adds quite a bit of complexity and is therefore not the most elegant solution.

Use symbols to prevent conflict

If the purpose is to prevent name conflicts, you can use Symbol to provide a useful solution. These are essentially instances that can act as unique values, and they will never equal any other value except its own unique instance. Here is an example of it in real-life applications:

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

  accelerate(amount) {
    // This data is almost impossible to access unexpectedly. It is by no means private.
    // But it stays away from anyone who will implement this module.
    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 -- We need to access the internal key to access the variable.

Like the underscore solution, this approach relies more or less on naming conventions to prevent confusion.

TC39 Private Class Field Proposal

Recently, a new proposal was proposed that would introduce private variables to the class. It's simple: add # before the variable name and it becomes private. No additional structural changes are required.

 class CarModule {
  #speed = 0
  #milesDriven = 0

  accelerate(amount) {
    // This data is almost impossible to access unexpectedly.
    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 -- We need to access the internal key to access the variable.

Private class features have become a reality and have quite good browser support.

in conclusion

This is a summary of the various ways to implement private variables in JavaScript. There is no "correct" approach. These methods are suitable for different requirements, existing code bases, and other constraints. While each approach has its advantages and disadvantages, ultimately, all approaches are equally effective as long as they effectively solve your problem.

Thank you for reading! I hope this gives you some insight on how to apply scope and variable privacy to improve your JavaScript code. This is a powerful technology that supports many different methods and makes your code easier to use and error-free. Try some new examples yourself to get a better feeling.

The above is the detailed content of Implementing Private Variables In JavaScript. For more information, please follow other related articles on the PHP Chinese website!

Statement of this Website
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn

Hot AI Tools

Undress AI Tool

Undress AI Tool

Undress images for free

Undresser.AI Undress

Undresser.AI Undress

AI-powered app for creating realistic nude photos

AI Clothes Remover

AI Clothes Remover

Online AI tool for removing clothes from photos.

Clothoff.io

Clothoff.io

AI clothes remover

Video Face Swap

Video Face Swap

Swap faces in any video effortlessly with our completely free AI face swap tool!

Hot Article

Hot Tools

Notepad++7.3.1

Notepad++7.3.1

Easy-to-use and free code editor

SublimeText3 Chinese version

SublimeText3 Chinese version

Chinese version, very easy to use

Zend Studio 13.0.1

Zend Studio 13.0.1

Powerful PHP integrated development environment

Dreamweaver CS6

Dreamweaver CS6

Visual web development tools

SublimeText3 Mac version

SublimeText3 Mac version

God-level code editing software (SublimeText3)

What is 'render-blocking CSS'? What is 'render-blocking CSS'? Jun 24, 2025 am 12:42 AM

CSS blocks page rendering because browsers view inline and external CSS as key resources by default, especially with imported stylesheets, header large amounts of inline CSS, and unoptimized media query styles. 1. Extract critical CSS and embed it into HTML; 2. Delay loading non-critical CSS through JavaScript; 3. Use media attributes to optimize loading such as print styles; 4. Compress and merge CSS to reduce requests. It is recommended to use tools to extract key CSS, combine rel="preload" asynchronous loading, and use media delayed loading reasonably to avoid excessive splitting and complex script control.

What is Autoprefixer and how does it work? What is Autoprefixer and how does it work? Jul 02, 2025 am 01:15 AM

Autoprefixer is a tool that automatically adds vendor prefixes to CSS attributes based on the target browser scope. 1. It solves the problem of manually maintaining prefixes with errors; 2. Work through the PostCSS plug-in form, parse CSS, analyze attributes that need to be prefixed, and generate code according to configuration; 3. The usage steps include installing plug-ins, setting browserslist, and enabling them in the build process; 4. Notes include not manually adding prefixes, keeping configuration updates, prefixes not all attributes, and it is recommended to use them with the preprocessor.

What is the conic-gradient() function? What is the conic-gradient() function? Jul 01, 2025 am 01:16 AM

Theconic-gradient()functioninCSScreatescirculargradientsthatrotatecolorstopsaroundacentralpoint.1.Itisidealforpiecharts,progressindicators,colorwheels,anddecorativebackgrounds.2.Itworksbydefiningcolorstopsatspecificangles,optionallystartingfromadefin

CSS tutorial for creating a sticky header or footer CSS tutorial for creating a sticky header or footer 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

What is the scope of a CSS Custom Property? What is the scope of a CSS Custom Property? Jun 25, 2025 am 12:16 AM

The scope of CSS custom properties depends on the context of their declaration, global variables are usually defined in :root, while local variables are defined within a specific selector for componentization and isolation of styles. For example, variables defined in the .card class are only available for elements that match the class and their children. Best practices include: 1. Use: root to define global variables such as topic color; 2. Define local variables inside the component to implement encapsulation; 3. Avoid repeatedly declaring the same variable; 4. Pay attention to the coverage problems that may be caused by selector specificity. Additionally, CSS variables are case sensitive and should be defined before use to avoid errors. If the variable is undefined or the reference fails, the fallback value or default value initial will be used. Debug can be done through the browser developer

What are fr units in CSS Grid? What are fr units in CSS Grid? Jun 22, 2025 am 12:46 AM

ThefrunitinCSSGriddistributesavailablespaceproportionally.1.Itworksbydividingspacebasedonthesumoffrvalues,e.g.,1fr2frgivesone-thirdandtwo-thirds.2.Itenablesflexiblelayouts,avoidsmanualcalculations,andsupportsresponsivedesign.3.Commonusesincludeequal-

CSS tutorial focusing on mobile-first design CSS tutorial focusing on mobile-first design Jul 02, 2025 am 12:52 AM

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

How to create an intrinsically responsive grid layout? How to create an intrinsically responsive grid layout? Jul 02, 2025 am 01:19 AM

To create an intrinsic responsive grid layout, the core method is to use CSSGrid's repeat(auto-fit,minmax()) mode; 1. Set grid-template-columns:repeat(auto-fit,minmax(200px,1fr)) to let the browser automatically adjust the number of columns and limit the minimum and maximum widths of each column; 2. Use gap to control grid spacing; 3. The container should be set to relative units such as width:100%, and use box-sizing:border-box to avoid width calculation errors and center them with margin:auto; 4. Optionally set the row height and content alignment to improve visual consistency, such as row

See all articles