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 相关文章推荐
飞鱼(shqlsl) javascript作品集
Dec 16 Javascript
jQuery中文入门指南,翻译加实例,jQuery的起点教程
Jan 13 Javascript
ext监听事件方法[初级篇]
Apr 27 Javascript
jQuery实现MSN中文网滑动Tab菜单效果代码
Sep 09 Javascript
jQuery控制文本框只能输入数字和字母及使用方法
May 26 Javascript
JavaScript中的Array 对象(数组对象)
Jun 02 Javascript
Servlet实现文件上传,可多文件上传示例
Dec 05 Javascript
JavaScript定时器制作弹窗小广告
Feb 05 Javascript
Node.js 异步异常的处理与domain模块解析
May 10 Javascript
JS实现指定区域的全屏显示功能示例
Apr 25 Javascript
layui table表格数据的新增,修改,删除,查询,双击获取行数据方式
Nov 14 Javascript
JS实现简易留言板特效
Dec 23 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根据地址获取百度地图经纬度的实例方法
2019/09/03 PHP
PHP实现chrome表单请求数据转换为接口使用的json数据
2021/03/04 PHP
event.srcElement 用法笔记e.target
2009/12/18 Javascript
Javascript的匿名函数小结
2009/12/31 Javascript
javascript模拟select,jselect的方法实现
2012/11/08 Javascript
jQuery插件 selectToSelect使用方法
2013/10/02 Javascript
JS实现的鼠标跟随代码(卡通手型点击效果)
2015/10/26 Javascript
JS获取IMG图片高宽的简单实例
2016/05/17 Javascript
ThinkJS中如何使用MongoDB的CURD操作
2016/12/13 Javascript
JS实现改变HTML上文字颜色和内容的方法
2016/12/30 Javascript
canvas实现图像放大镜
2017/02/06 Javascript
关于axios返回空对象的问题解决
2017/04/04 Javascript
静态页面实现 include 引入公用代码的示例
2017/09/25 Javascript
AngularJS实现表单验证功能详解
2017/10/12 Javascript
jQuery进阶实践之利用最优雅的方式如何写ajax请求
2017/12/20 jQuery
详解vue移动端项目代码拆分记录
2019/03/15 Javascript
Vue组件实现触底判断
2019/06/26 Javascript
jQuery操作元素追加内容示例
2020/01/10 jQuery
[03:53]2016国际邀请赛中国区预选赛第三日TOP10精彩集锦
2016/06/29 DOTA
[01:22:19]EG vs TNC Supermajor小组赛B组败者组第一轮 BO3 第二场 6.2
2018/06/03 DOTA
python中django框架通过正则搜索页面上email地址的方法
2015/03/21 Python
老生常谈Python序列化和反序列化
2017/06/28 Python
Django 路由控制的实现代码
2018/11/08 Python
python 实现list或string按指定分段
2019/12/25 Python
Python 文件数据读写的具体实现
2020/01/24 Python
使用keras实现孪生网络中的权值共享教程
2020/06/11 Python
HTML5 客户端数据库简易使用:IndexedDB
2019/12/19 HTML / CSS
跟单文员岗位职责
2014/01/03 职场文书
实验心得体会
2014/09/05 职场文书
2014年国庆晚会主持词
2014/09/19 职场文书
婚前协议书标准版
2014/10/19 职场文书
2015年初中元旦晚会活动总结
2014/11/28 职场文书
会计岗位职责范本
2015/04/02 职场文书
CSS3 Tab动画实例之背景切换动态效果
2021/08/23 HTML / CSS
Windows Server 2012配置DNS服务器的方法
2022/04/29 Servers
spring boot实现文件上传
2022/08/14 Java/Android