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 相关文章推荐
解析Javascript小括号“()”的多义性
Dec 03 Javascript
JavaScript计时器示例分析
Feb 05 Javascript
js实现文本框中输入文字页面中div层同步获取文本框内容的方法
Mar 03 Javascript
javascript中this指向详解
Apr 23 Javascript
JavaScript 对象详细整理总结
Sep 29 Javascript
seajs模块之间依赖的加载以及模块的执行
Oct 21 Javascript
canvas 弹幕效果(实例分享)
Jan 11 Javascript
JS中利用localStorage防止页面动态添加数据刷新后数据丢失
Mar 10 Javascript
前端开发不得不知的10个最佳ES6特性
Aug 30 Javascript
jQuery实现验证表单密码一致性及正则表达式验证邮箱、手机号的方法
Dec 05 jQuery
Element实现表格分页数据选择+全选所有完善批量操作
Jun 07 Javascript
jQuery实现带进度条的轮播图
Sep 13 jQuery
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+Tidy-完美的XHTML纠错+过滤
2007/04/10 PHP
php结合md5实现的加密解密方法
2016/01/25 PHP
php编程每天必学之表单验证
2016/03/01 PHP
PHP常见数组函数用法小结
2016/03/21 PHP
PHP入门教程之数组用法汇总(创建,删除,遍历,排序等)
2016/09/11 PHP
CI(CodeIgniter)框架实现图片上传的方法
2017/03/24 PHP
PHP里面把16进制的图片数据显示在html的img标签上(实现方法)
2017/05/02 PHP
Yii 实现数据加密和解密
2021/03/09 PHP
学习javascript,实现插入排序实现代码
2011/07/31 Javascript
javascript中的delete使用详解
2013/04/11 Javascript
Jquery中Event对象属性小结
2015/02/27 Javascript
javascript使用输出语句实现网页特效代码
2015/08/06 Javascript
JavaScript中的操作符类型转换示例总结
2016/05/30 Javascript
带有定位当前位置的百度地图前端web api实例代码
2016/06/21 Javascript
详解NODEJS基于FFMPEG视频推流测试
2017/11/17 NodeJs
详解vue组件中使用路由方法
2019/02/12 Javascript
微信小程序wx.request拦截器使用详解
2019/07/09 Javascript
VUE项目中加载已保存的笔记实例方法
2019/09/14 Javascript
javascript用defineProperty实现简单的双向绑定方法
2020/04/03 Javascript
Python的Django框架中模板碎片缓存简介
2015/07/24 Python
在Mac OS系统上安装Python的Pillow库的教程
2015/11/20 Python
Python 多线程实例详解
2017/03/25 Python
python 调用有道api接口的方法
2019/01/03 Python
对Python使用mfcc的两种方式详解
2019/01/09 Python
Python绘制频率分布直方图的示例
2019/07/08 Python
Python爬取破解无线网络wifi密码过程解析
2019/09/17 Python
Django中和时区相关的安全问题详解
2020/10/12 Python
canvas简易绘图的实现(海绵宝宝篇)
2018/07/04 HTML / CSS
在网上学习全世界最好的课程:Coursera
2017/11/07 全球购物
Java的for语句中break, continue和return的区别
2013/12/19 面试题
2014年客户经理工作总结
2014/11/20 职场文书
天河观后感
2015/06/11 职场文书
2015年行政管理人员工作总结
2015/10/15 职场文书
如何使用Python实现一个简易的ORM模型
2021/05/12 Python
HDFS免重启挂载新磁盘
2022/04/06 Servers