好得很程序员自学网

<tfoot draggable='sEl'></tfoot>

JavaScript 声明私有变量的两种方式

前言

JavaScript并不像别的语言,能使用关键字来声明私有变量。
我了解的JavaScript能用来声明私有变量的方式有两种,一种是使用闭包,一种是使用WeakMap。

闭包

闭包的描述有很多种,比如:
能访问其它函数作用域的函数;
内部函数访问外部函数作用域的桥梁;
......

使用闭包构建私有变量的逻辑在于:
1.在外部函数中声明变量和内部函数;
2.使用内部函数访问或者修改变量值;
3.在外部函数内返回内部函数;

?

function outside(){

     let val = 123;

     function inside(){

         return val;

     }

     return inside;

}

console.log(outside()()); //123

通过我上面的例子能够大致了解使用闭包构建私有变量的逻辑,但是不足以体现私有变量的重要性,一个const变量也能达到上述代码的效果:

?

//同样的能访问,但是不能修改,达到了上述代码的效果

const val = 123;

console.log(val); //123

接下来的代码,将具体体现私有变量的重要性:

?

function person(){

  let _name = 'unknown' ;

  let _age = 18;

  let _sex = 'man' ;

 

  function setName(name){

   _name = name || 'unknown' ;

  }

 

  function getName(){

   return _name;

  }

 

  function setAge(age){

   if ( typeof age === 'number' ){

    _age = Math.floor(age);

   } else {

    throw Error( "typeof age !== 'number'" );

   }

  }

 

  function getAge(){

   return _age;

  }

 

  function setSex(sex){

   if (sex === 'man' || sex === 1){

    _sex = 'man' ;

   } else if (sex === 'woman' || sex === 0){

    _sex = 'woman' ;

   } else {

    throw Error( 'input error' );

   }

  }

 

  function getSex(){

   return _sex;

  }

 

  return {

   setName : setName,

   getName : getName,

   setAge : setAge,

   getAge : getAge,

   setSex : setSex,

   getSex : getSex

  }

}

 

let xiaoming = person();

let xiaohong = person();

xiaoming.setName( 'xiaoming' );

xiaohong.setName( 'xiaohong' );

console.log( 'xiaoming name : ' + xiaoming.getName()); //xiaoming name : xiaoming

console.log( 'xiaohong name : ' + xiaohong.getName()); //xiaohong name : xiaohong

 

xiaoming.setAge(19.3333);

xiaohong.setAge( '16' ); //Uncaught Error: typeof age !== 'number'

console.log( 'xiaoming age : ' + xiaoming.getAge()); //xiaoming age : 19

console.log( 'xiaohong age : ' + xiaohong.getAge()); //xiaohong age : 18

 

 

xiaoming.setSex(1);

xiaohong.setSex( 'woman' );

console.log( 'xiaoming sex : ' + xiaoming.getSex()); //xiaoming sex : man

console.log( 'xiaohong sex : ' + xiaohong.getSex()); //xiaohong sex : woman

从上面的代码中,可以看出,如果想要设置或者获取 _name、_age、_sex三个变量的值,只能通过固定的 setName、getName、setAge、getAge、setSex、getSex等方法,而在所有的setter方法中,都对形参进行了判断。也就意味着,对对象的所有操作都将在掌控之中,这在某一层面上弱化了JavaScript作为弱类型语言上的一些负面影响。

WeakMap

如果对WeakMap不是很了解的可以先看 WeakMap的详细介绍 。
这里主要是利用WeakMap的key不可枚举这一知识点。

?

let nameWeakMap = new WeakMap();

let ageWeakMap = new WeakMap();

let sexWeakMap = new WeakMap();

 

function person(){

  let _hash = Object.create( null );

  nameWeakMap.set(_hash, 'unknown' );

  ageWeakMap.set(_hash,18);

  sexWeakMap.set(_hash, 'man' );

  function setName(name){

   nameWeakMap.set(_hash,name || 'unknown' );

  }

 

  function getName(){

   return nameWeakMap.get(_hash);

  }

 

  function setAge(age){

   if ( typeof age === 'number' ){

    ageWeakMap.set(_hash,Math.floor(age));

   } else {

    throw Error( "typeof age !== 'number'" );

   }

  }

 

  function getAge(){

   return ageWeakMap.get(_hash);

  }

 

  function setSex(sex){

   if (sex === 'man' || sex === 1){

    sexWeakMap.set(_hash, 'man' );

   } else if (sex === 'woman' || sex === 0){

    sexWeakMap.set(_hash, 'woman' );

   } else {

    throw Error( 'input error' );

   }

  }

 

  function getSex(){

   return sexWeakMap.get(_hash);

  }

 

  return {

   setName : setName,

   getName : getName,

   setAge : setAge,

   getAge : getAge,

   setSex : setSex,

   getSex : getSex

  }

}

 

let xiaoming = person();

let xiaohong = person();

xiaoming.setName( 'xiaoming' );

xiaohong.setName( 'xiaohong' );

console.log( 'xiaoming name : ' + xiaoming.getName()); //xiaoming name : xiaoming

console.log( 'xiaohong name : ' + xiaohong.getName()); //xiaohong name : xiaohong

 

xiaoming.setAge(19.3333);

xiaohong.setAge( '16' ); //Uncaught Error: typeof age !== 'number'

console.log( 'xiaoming age : ' + xiaoming.getAge()); //xiaoming age : 19

console.log( 'xiaohong age : ' + xiaohong.getAge()); //xiaohong age : 18

 

 

xiaoming.setSex(1);

xiaohong.setSex( 'woman' );

console.log( 'xiaoming sex : ' + xiaoming.getSex()); //xiaoming sex : man

console.log( 'xiaohong sex : ' + xiaohong.getSex()); //xiaohong sex : woman

同样达成了构建私有变量的效果。顺便提一句,class中构建私有变量用的就是WeakMap。

结尾

这篇文章只是记录我知道的关于JavaScript构建私有变量的方法以及作用,如有错误和遗漏,欢迎指出,不胜感谢。

以上就是JavaScript 声明私有变量的两种方式的详细内容,更多关于JavaScript 声明私有变量的资料请关注服务器之家其它相关文章!

原文链接:https://www.cnblogs.com/liujingjiu/p/14377246.html

查看更多关于JavaScript 声明私有变量的两种方式的详细内容...

  阅读:38次