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


Posted in Javascript onFebruary 05, 2021

前言

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 声明私有变量的资料请关注三水点靠木其它相关文章!

Javascript 相关文章推荐
js获取提交的字符串的字节数
Feb 09 Javascript
JavaScript 获取事件对象的注意点
Jul 29 Javascript
基于jquery的tab切换 js原理
Apr 01 Javascript
jQuery EasyUI 的EasyLoader功能介绍
Sep 12 Javascript
Javascript延迟执行实现方法(setTimeout)
Dec 30 Javascript
JS中判断JSON数据是否存在某字段的方法
Mar 07 Javascript
Node.js和PHP根据ip获取地理位置的方法
Mar 14 Javascript
一个不错的字符串转码解码函数(自写)
Jul 31 Javascript
jquery实现倒计时效果
Dec 14 Javascript
vue滚动插件better-scroll使用详解
Oct 18 Javascript
js实现简单掷骰子效果
Oct 24 Javascript
详解JSON.parse和JSON.stringify用法
Feb 18 Javascript
node.js文件的复制、创建文件夹等相关操作
Feb 05 #Javascript
Vant+postcss-pxtorem 实现浏览器适配功能
Feb 05 #Javascript
JavaScript代码实现微博批量取消关注功能
Feb 05 #Javascript
js属性对象的hasOwnProperty方法的使用
Feb 05 #Javascript
关于element的表单组件整理笔记
Feb 05 #Javascript
详解JavaScript中的this指向问题
Feb 05 #Javascript
JavaScript事件概念详解(区分静态注册和动态注册)
Feb 05 #Javascript
You might like
PHP新手上路(十二)
2006/10/09 PHP
《PHP边学边教》(04.编写简易的通讯录――视频教程1)
2006/12/13 PHP
解析PHP自带的进位制之间的转换函数
2013/06/08 PHP
php内核解析:PHP中的哈希表
2014/01/30 PHP
Laravel 5框架学习之Blade 简介
2015/04/08 PHP
php中注册器模式类用法实例分析
2015/11/03 PHP
thinkphp框架实现删除和批量删除
2016/06/29 PHP
thinkPHP交易详情查询功能详解
2016/12/02 PHP
Javascript四舍五入Math.round()与Math.pow()使用介绍
2013/12/27 Javascript
利用jQuery设计一个简单的web音乐播放器的实例分享
2016/03/08 Javascript
js闭包引起的事件注册问题介绍
2016/03/29 Javascript
Javascript日期格式化format函数的使用方法
2016/08/30 Javascript
jquery实现图片上传前本地预览
2017/04/28 jQuery
微信小程序动态显示项目倒计时效果
2017/06/13 Javascript
jquery单击文字或图片内容放大并居中显示
2017/06/23 jQuery
关于Vue背景图打包之后访问路径错误问题的解决
2017/11/03 Javascript
详解redux异步操作实践
2018/08/15 Javascript
微信小程序实现判断是分享到群还是个人功能示例
2019/05/03 Javascript
python 从远程服务器下载日志文件的程序
2013/02/10 Python
python 网络编程常用代码段
2016/08/28 Python
Python中标准库OS的常用方法总结大全
2017/07/19 Python
分享一下如何编写高效且优雅的 Python 代码
2017/09/07 Python
用python实现的线程池实例代码
2018/01/06 Python
Python使用Excel将数据写入多个sheet
2020/05/16 Python
Python字符串查找基本操作代码案例
2020/10/27 Python
用HTML5中的Canvas结合公式绘制粒子运动的教程
2015/05/08 HTML / CSS
Foot Locker意大利官网:全球领先的运动鞋和服装零售商
2017/05/30 全球购物
美国汽车性能部件和赛车零件网站:Vivid Racing
2018/03/27 全球购物
法学毕业生自荐信
2013/11/13 职场文书
人力资源经理自我评价
2014/01/04 职场文书
庆祝国庆节标语
2014/10/09 职场文书
办公室卫生管理制度
2015/08/04 职场文书
银行求职信范文
2019/05/13 职场文书
2019年手机市场的调研报告2篇
2019/10/10 职场文书
Redis Cluster集群动态扩容的实现
2021/07/15 Redis
virtualenv隔离Python环境的问题解析
2022/06/21 Python