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 调试利器 Firebug使用详解六
Jul 05 Javascript
基于jquery的回到页面顶部按钮
Jun 27 Javascript
js滚动条回到顶部的代码
Dec 06 Javascript
JS判断当前日期是否大于某个日期的实现代码
Sep 02 Javascript
了不起的node.js读书笔记之例程分析
Dec 22 Javascript
javascript自动生成包含数字与字符的随机字符串
Feb 09 Javascript
JQuery基础语法小结
Feb 27 Javascript
JQuery球队选择实例
May 18 Javascript
基于JavaScript实现点击页面任何位置返回
Aug 31 Javascript
jQuery制作input提示内容(兼容IE8以上)
Jul 05 jQuery
微信小程序学习笔记之文件上传、下载操作图文详解
Mar 29 Javascript
Vue指令之 v-cloak、v-text、v-html实例详解
Aug 08 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
linux下 C语言对 php 扩展
2008/12/14 PHP
PHP信号量基本用法实例详解
2016/02/12 PHP
在PHP语言中使用JSON和将json还原成数组的方法
2016/07/19 PHP
PHP7新特性foreach 修改示例介绍
2016/08/26 PHP
php实现的中秋博饼游戏之掷骰子并输出结果功能详解
2017/11/06 PHP
使两个iframe的高度与内容自适应,且相等
2006/11/20 Javascript
Jquery+ajax请求data显示在GridView上(asp.net)
2010/08/27 Javascript
动态加载图片路径 保持JavaScript控件的相对独立性
2010/09/03 Javascript
中文字符串截取的js函数代码
2013/04/17 Javascript
解析img图片没找到onerror事件 Stack overflow at line: 0
2013/12/23 Javascript
通过遮罩层实现浮层DIV登录的js代码
2014/02/07 Javascript
JS实现根据当前文字选择返回被选中的文字
2014/05/21 Javascript
原生JavaScript实现瀑布流布局
2020/06/28 Javascript
JavaScript实现iframe自动高度调整和不同主域名跨域
2016/02/27 Javascript
JavaScript实现简单的拖动效果
2016/07/02 Javascript
基于MVC+EasyUI的web开发框架之使用云打印控件C-Lodop打印页面或套打报关运单信息
2016/08/29 Javascript
jQuery实现的简单悬浮层功能完整实例
2017/01/23 Javascript
ionic grid(栅格)九宫格制作详解
2018/06/30 Javascript
VUE中v-on:click事件中获取当前dom元素的代码
2018/08/22 Javascript
vue中多路由表头吸顶实现的几种布局方式
2019/04/12 Javascript
Vue调用后端java接口的实例代码
2019/10/28 Javascript
vue 解决移动端弹出键盘导致页面fixed布局错乱的问题
2019/11/06 Javascript
使用vue-cli3+typescript的项目模板创建工程的教程
2020/02/28 Javascript
vue路由分文件拆分管理详解
2020/08/13 Javascript
[42:52]IG vs VGJ.T 2018国际邀请赛小组赛BO2 第二场 8.18
2018/08/19 DOTA
详解Python的Twisted框架中reactor事件管理器的用法
2016/05/25 Python
Python3基于sax解析xml操作示例
2018/05/22 Python
基于python3实现socket文件传输和校验
2018/07/28 Python
Python玩转Excel的读写改实例
2019/02/22 Python
python ssh 执行shell命令的示例
2020/09/29 Python
网络程序员自荐信
2014/01/25 职场文书
高中军训第一天感言
2014/03/06 职场文书
借款协议书范本
2014/04/22 职场文书
治庸问责工作总结
2015/08/11 职场文书
日本官方排名前10的动漫,名侦探柯南上榜,第一是一部创造历史的动漫
2022/03/18 日漫
Python可视化神器pyecharts绘制地理图表
2022/07/07 Python