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 获取用户客户端操作系统版本
Aug 25 Javascript
js数据验证集合、js email验证、js url验证、js长度验证、js数字验证等简单封装
May 15 Javascript
jQuery源码解读之hasClass()方法分析
Feb 20 Javascript
JavaScript移除数组内重复元素的方法
Mar 18 Javascript
JavaScript使用Prototype实现面向对象的方法
Apr 14 Javascript
javascript等号运算符使用详解
Apr 16 Javascript
JavaScript实现图片轮播的方法
Jul 31 Javascript
javascript实现不同颜色Tab标签切换效果
Apr 27 Javascript
JS中关于事件处理函数名后面是否带括号的问题
Nov 16 Javascript
vue项目在安卓低版本机显示空白的原因分析(两种)
Sep 04 Javascript
layUI实现前端分页和后端分页
Jul 27 Javascript
vue实现点击出现操作弹出框的示例
Nov 05 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中养成7个面向对象的好习惯
2010/01/28 PHP
PHPMailer邮件发送的实现代码
2013/05/04 PHP
基于AppServ,XAMPP,WAMP配置php.ini去掉警告信息(NOTICE)的方法详解
2013/05/07 PHP
PHP字符串中特殊符号的过滤方法介绍
2014/02/18 PHP
php中curl和file_get_content的区别
2014/05/10 PHP
php使用curl通过代理获取数据的实现方法
2016/05/16 PHP
php使用PDO执行SQL语句的方法分析
2017/02/16 PHP
PHP正则匹配到2个字符串之间的内容方法
2018/12/24 PHP
小程序微信退款功能实现方法详解【基于thinkPHP】
2019/05/05 PHP
javascript下对于事件、事件流、事件触发的顺序随便说说
2010/07/17 Javascript
Ajax执行顺序流程及回调问题分析
2012/12/10 Javascript
JS 如何获取radio选中后的值及不选择取radio的值
2013/10/28 Javascript
javascript 自定义回调函数示例代码
2014/09/26 Javascript
jquery实现submit提交表单
2015/02/03 Javascript
JavaScript中的setMilliseconds()方法使用详解
2015/06/11 Javascript
解决jquery无法找到其他父级子集问题的方法
2016/05/10 Javascript
动手写一个angular版本的Message组件的方法
2017/12/16 Javascript
基于vue-cli vue-router搭建底部导航栏移动前端项目
2018/02/28 Javascript
Vue中通过属性绑定为元素绑定style行内样式的实例代码
2020/04/30 Javascript
Javascript实现鼠标移入方向感知
2020/06/24 Javascript
实用的 vue tags 创建缓存导航的过程实现
2020/12/03 Vue.js
[44:33]EG vs Liquid 2018国际邀请赛小组赛BO2 第二场 8.18
2018/08/19 DOTA
python获得图片base64编码示例
2014/01/16 Python
对于Python中线程问题的简单讲解
2015/04/03 Python
详解Python的Lambda函数与排序
2016/10/25 Python
python贪婪匹配以及多行匹配的实例讲解
2018/04/19 Python
解决python报错MemoryError的问题
2018/06/26 Python
Python Django Vue 项目创建过程详解
2019/07/29 Python
Python列表切片常用操作实例解析
2020/03/10 Python
Python操作word文档插入图片和表格的实例演示
2020/10/25 Python
python中PyQuery库用法分享
2021/01/15 Python
班委竞选演讲稿
2014/04/28 职场文书
竞选学习委员演讲稿
2014/04/28 职场文书
国际贸易系求职信
2014/08/09 职场文书
员工三分钟演讲稿
2014/08/19 职场文书
爱心捐赠活动简讯
2015/07/20 职场文书