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 相关文章推荐
JSP跨iframe如何传递参数实现代码
Sep 21 Javascript
在父页面调用子页面的JS方法
Sep 29 Javascript
使用jquery实现的一个图片延迟加载插件(含图片延迟加载原理)
Jun 05 Javascript
常用jQuery代码分享
Jul 14 Javascript
页面内容排序插件jSort使用方法
Oct 10 Javascript
jQuery Validate插件实现表单验证
Aug 19 Javascript
bootstrap实现的自适应页面简单应用示例
Mar 09 Javascript
JavaScrpt的面向对象全面解析
May 09 Javascript
原生JS实现图片懒加载(lazyload)实例
Jun 13 Javascript
Vue使用Canvas绘制图片、矩形、线条、文字,下载图片
Apr 26 Javascript
浅谈React中组件逻辑复用的那些事儿
May 21 Javascript
vue2.0实现列表数据增加和删除
Jun 17 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模板之Phpbean的目录结构
2008/01/10 PHP
由php的call_user_func传reference引发的思考
2010/07/23 PHP
php解析html类库simple_html_dom(详细介绍)
2013/07/05 PHP
用Zend Studio+PHPnow+Zend Debugger搭建PHP服务器调试环境步骤
2014/01/19 PHP
smarty模板引擎之配置文件数据和保留数据
2015/03/30 PHP
php实现修改新闻时删除图片的方法
2015/05/12 PHP
PHP使用pear实现mail发送功能 windows环境下配置pear
2016/04/15 PHP
goto语法在PHP中的使用教程
2020/09/17 PHP
用javascript实现自定义标签
2007/05/08 Javascript
Jquery Autocomplete 结合asp.net使用要点
2010/10/29 Javascript
基于jquery的一行代码轻松实现拖动效果
2010/12/28 Javascript
实现无刷新联动例子汇总
2015/05/20 Javascript
全屏js头像上传插件源码高清版
2016/03/29 Javascript
在原生不支持的旧环境中添加兼容的Object.keys实现方法
2017/09/11 Javascript
详解axios 全攻略之基本介绍与使用(GET 与 POST)
2017/09/15 Javascript
十分钟带你快速了解React16新特性
2017/11/10 Javascript
解决vue select当前value没有更新到vue对象属性的问题
2018/08/30 Javascript
JS实现带阴历的日历功能详解
2019/01/24 Javascript
微信二次分享报错invalid signature问题及解决方法
2019/04/01 Javascript
Servlet返回的数据js解析2种方法
2019/12/12 Javascript
js实现旋转木马轮播图效果
2020/01/10 Javascript
Vue中this.$nextTick的作用及用法
2020/02/04 Javascript
javascript设计模式 ? 装饰模式原理与应用实例分析
2020/04/14 Javascript
在Python的web框架中中编写日志列表的教程
2015/04/30 Python
Python编程中的文件操作攻略
2015/10/16 Python
Python基于time模块求程序运行时间的方法
2017/09/18 Python
python3.6使用urllib完成下载的实例
2018/12/19 Python
python logging模块书写日志以及日志分割详解
2019/07/22 Python
NUK奶瓶美国官网:NUK美国
2016/09/26 全球购物
资产评估专业大学生求职信
2013/09/29 职场文书
中职应届生会计求职信
2013/10/23 职场文书
股东授权委托书范本
2014/09/13 职场文书
办理房产过户的委托书
2014/09/14 职场文书
观看建国大业观后感
2015/06/01 职场文书
孟佩杰观后感
2015/06/17 职场文书
python神经网络学习 使用Keras进行简单分类
2022/05/04 Python