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 相关文章推荐
处理及遍历XML文档DOM元素属性及方法整理
Aug 23 Javascript
用jquery写的一个万年历(自写)
Jan 20 Javascript
浅谈javascript对象模型和function对象
Dec 26 Javascript
判断浏览器的内核及版本号方法汇总
Jan 05 Javascript
基于jQuery实现响应式圆形图片轮播特效
Nov 25 Javascript
原生js和jquery分别实现横向导航菜单效果
May 13 Javascript
简单封装js的dom查询实例代码
Jul 08 Javascript
基于JavaScript实现自动更新倒计时效果
Dec 19 Javascript
React Native 集成jpush-react-native的示例代码
Aug 16 Javascript
基于vue开发的在线付费课程应用过程
Jan 25 Javascript
Vue修改mint-ui默认样式的方法
Feb 03 Javascript
node之本地服务器图片上传的方法示例
Mar 26 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
Discuz! Passport 通行证整合
2008/03/27 PHP
PHP 输出简单动态WAP页面
2009/06/09 PHP
简介WordPress中用于获取首页和站点链接的PHP函数
2015/12/17 PHP
解决ThinkPHP下使用上传插件Uploadify浏览器firefox报302错误的方法
2015/12/18 PHP
Yii使用Captcha验证码的方法
2015/12/28 PHP
理清PHP在Linxu下执行时的文件权限方法
2017/06/07 PHP
javascript 设置某DIV区域内的checkbox复选框
2009/11/30 Javascript
javascript删除数组重复元素的方法汇总
2015/06/24 Javascript
如何利用JS通过身份证号获取当事人的生日、年龄、性别
2016/01/22 Javascript
Ext JS框架中日期函数的用法及日期选择控件的实现
2016/05/21 Javascript
详解JavaScript中数组的reduce方法
2016/12/02 Javascript
利用ES6的Promise.all实现至少请求多长时间的实例
2017/08/28 Javascript
详解vue-cli中的ESlint配置文件eslintrc.js
2017/09/25 Javascript
nodeJS服务器的创建和重新启动的实现方法
2018/05/12 NodeJs
微信小程序列表中item左滑删除功能
2018/11/07 Javascript
Vue插件之滑动验证码
2019/09/21 Javascript
layui树形菜单动态遍历的例子
2019/09/23 Javascript
linux系统使用python监测网络接口获取网络的输入输出
2014/01/15 Python
Python中DJANGO简单测试实例
2015/05/11 Python
Python面向对象编程基础解析(一)
2017/10/26 Python
Python subprocess模块功能与常见用法实例详解
2018/06/28 Python
pycharm配置pyqt5-tools开发环境的方法步骤
2019/02/11 Python
对django 模型 unique together的示例讲解
2019/08/06 Python
Django框架安装方法图文详解
2019/11/04 Python
Python字符串、列表、元组、字典、集合的补充实例详解
2019/12/20 Python
python numpy 矩阵堆叠实例
2020/01/17 Python
详解pyqt5的UI中嵌入matplotlib图形并实时刷新(挖坑和填坑)
2020/08/07 Python
IE浏览器单独写CSS样式的几种方法
2014/10/14 HTML / CSS
Vilebrequin美国官方网上商店:法国豪华泳装品牌
2020/02/22 全球购物
打架检讨书2000字
2014/02/22 职场文书
先进典型发言材料
2014/12/30 职场文书
市场总监岗位职责
2015/02/11 职场文书
刑事撤诉申请书
2015/05/18 职场文书
信息技术远程培训心得体会
2016/01/09 职场文书
Python基础之元类详解
2021/04/29 Python
MYSQL如何查看进程和kill进程
2022/03/13 MySQL