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 相关文章推荐
多个iframe自动调整大小的问题
Sep 18 Javascript
JQuery防止退格键网页后退的实现代码
Mar 23 Javascript
JQUERY实现左侧TIPS滑进滑出效果示例
Jun 27 Javascript
JQuery中的事件及动画用法实例
Jan 26 Javascript
JavaScript中实现map功能代码分享
Jun 11 Javascript
jquery SweetAlert插件实现响应式提示框
Aug 18 Javascript
jquery实现带缩略图的可定制高度画廊效果(5种)
Aug 28 Javascript
Laydate时间组件在火狐浏览器下有多时间输入框时只能给第一个输入框赋值的解决方法
Aug 18 Javascript
浅谈Vue.js
Mar 02 Javascript
vue使用iframe嵌入网页的示例代码
Jun 09 Javascript
Js Snowflake(雪花算法)生成随机ID的实现方法
Aug 26 Javascript
vue监听浏览器原生返回按钮,进行路由转跳操作
Sep 09 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中error_reporting()用法详解
2015/08/31 PHP
PHP+AJAX实现投票功能的方法
2015/09/28 PHP
PHP利用Cookie设置用户30分钟未操作自动退出功能
2017/07/03 PHP
对于Laravel 5.5核心架构的深入理解
2018/02/22 PHP
Laravel框架实现利用监听器进行sql语句记录功能
2018/06/06 PHP
用js实现的页面关键字密度查询代码
2007/12/27 Javascript
js 格式化时间日期函数小结
2010/03/20 Javascript
js 全兼容可高亮二级缓冲折叠菜单
2010/06/04 Javascript
sencha touch 模仿tabpanel导航栏TabBar的实例代码
2013/10/24 Javascript
jquery动态更换设置背景图的方法
2014/03/25 Javascript
jQuery实现HTML5 placeholder效果实例
2014/12/09 Javascript
javascript 实现文本使用省略号替代(超出固定高度的情况)
2017/02/21 Javascript
利用vscode编写vue的简单配置详解
2017/06/17 Javascript
Easyui Datagrid自定义按钮列(最后面的操作列)
2017/07/13 Javascript
使用Vue构建可重用的分页组件
2018/03/26 Javascript
小程序异步问题之多个网络请求依次执行并依次收集请求结果
2019/05/05 Javascript
微信小程序实现轨迹回放的示例代码
2019/12/13 Javascript
python登录豆瓣并发帖的方法
2015/07/08 Python
python开发之str.format()用法实例分析
2016/02/22 Python
python 读取.csv文件数据到数组(矩阵)的实例讲解
2018/06/14 Python
python多继承(钻石继承)问题和解决方法简单示例
2019/10/21 Python
导入tensorflow:ImportError: libcublas.so.9.0 报错
2020/01/06 Python
python 对一幅灰度图像进行直方图均衡化
2020/10/27 Python
捷克厨房用品购物网站:Tescoma
2018/07/13 全球购物
英国高街奥特莱斯:Highstreet Outlet
2019/11/21 全球购物
大学生专科毕业生自我评价
2013/11/17 职场文书
两年的个人工作自我评价
2014/01/10 职场文书
电话客服专员岗位职责
2014/06/28 职场文书
村主任群众路线个人对照检查材料
2014/09/26 职场文书
业务员岗位职责范本
2015/04/03 职场文书
公司酒会主持词
2015/07/02 职场文书
2015年中秋节主持词
2015/07/30 职场文书
幼儿园大班教学反思
2016/03/02 职场文书
2016年“我们的节日·端午节”活动总结
2016/04/01 职场文书
解决python3安装pandas出错的问题
2021/05/20 Python
Hive HQL支持2种查询语句风格
2022/06/25 数据库