JavaScript并不像别的语言,能使用关键字来声明私有变量。我了解的JavaScript能用来声明私有变量的方式有两种,一种是使用闭包,一种是使用WeakMap。

前言

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 : xiaomingconsole.log('xiaohong name : ' + xiaohong.getName());//xiaohong name : xiaohongxiaoming.setAge(19.3333);xiaohong.setAge('16');//Uncaught Error: typeof age !== 'number'console.log('xiaoming age : ' + xiaoming.getAge());//xiaoming age : 19console.log('xiaohong age : ' + xiaohong.getAge());//xiaohong age : 18xiaoming.setSex(1);xiaohong.setSex('woman');console.log('xiaoming sex : ' + xiaoming.getSex());//xiaoming sex : manconsole.log('xiaohong sex : ' + xiaohong.getSex());//xiaohong sex : woman

从上面的代码中,可以看出,如果想要设置或者获取 _name_age_sex三个变量的值,只能通过固定的 setNamegetNamesetAgegetAgesetSexgetSex等方法,而在所有的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 : xiaomingconsole.log('xiaohong name : ' + xiaohong.getName());//xiaohong name : xiaohongxiaoming.setAge(19.3333);xiaohong.setAge('16');//Uncaught Error: typeof age !== 'number'console.log('xiaoming age : ' + xiaoming.getAge());//xiaoming age : 19console.log('xiaohong age : ' + xiaohong.getAge());//xiaohong age : 18xiaoming.setSex(1);xiaohong.setSex('woman');console.log('xiaoming sex : ' + xiaoming.getSex());//xiaoming sex : manconsole.log('xiaohong sex : ' + xiaohong.getSex());//xiaohong sex : woman

同样达成了构建私有变量的效果。顺便提一句,class中构建私有变量用的就是WeakMap。

结尾

这篇文章只是记录我知道的关于JavaScript构建私有变量的方法以及作用,如有错误和遗漏,欢迎指出,不胜感谢。

JavaScript中是如何定义私有变量的的更多相关文章

  1. 浅谈JavaScript代码性能优化2

    一.减少判断层级 从下图代码中可以明显看出,同样的效果判断层级的减少可以优化性能二.减少作用域链查找层级 简单解释下......

  2. JavaScript this关键字的深入详解

    一、前言this关键字是JavaScript中最复杂的机制之一。它是一个很特别的关键字,被自动定义在所有函数的作用域......

  3. JS中循环遍历数组的四种方式总结

    本文比较并总结遍历数组的四种方式:for 循环:for (let index=0; index < someA......

  4. js简单粗暴的发布订阅示例代码

    什么是发布/订阅?我打个比方,你去某个门店买衣服,你和门店店长相互并不认识,门店店长只管卖他的衣服,并不关心是谁来买......

  5. jQuery+css实现的点击图片放大缩小预览功能示例【图片预览 查看大图】

    本文实例讲述了jQuery+css实现的点击图片放大缩小预览功能。分享给大家供大家参考,具体如下:要求点击一张图片,......

  6. jQuery中toggle与slideToggle以及fadeToggle的显示、隐藏方法的比较

    1、区别 ①动画效果的比较: toggle:直接显示、隐藏,如果有【时间参数】且【匹配的元素有宽度属性】,则动态效果......

  7. JavaScript canvas实现文字时钟

    本文实例为大家分享了canvas实现文字时钟的具体代码,供大家参考,具体内容如下 先看看效果图 代码 &l......

  8. javascript中call,apply,bind的区别详解

    在JS中,这三者都是用来改变函数的this对象的指向的,他们有什么样的区别呢。在说区别之前还是先总结一下三者的相似之......

  9. jquery表格插件Datatables使用、快速上手

    Datatables使用一、简介官网:https://datatables.net/ 中文官网:http://dat......

  10. 原生JavaScript实现轮播图

    本文实例为大家分享了JavaScript实现轮播图的具体代码,供大家参考,具体内容如下效果:代码:* {margin......

随机推荐

  1. c#定时执行程序代码

    在一般的项目中我们很少用到c#实现每隔规定时间自动执行程序代码,但是如果你经历的项目多,或者应用程序做的比较多的话,......

  2. 使用fdopen对python进程产生的文件进行权限最小化配置

    通过一定的文件访问权限的指定,我们可以使用fdopen来替代经常使用的内置的open库,来进行文件的创建和读写的操作......

  3. javascript脚本何时会被执行

    javascript脚本可以嵌入在html内的任意地方,但它何时被调用呢?当浏览器打开HTML文件后,会直接运行不是......

  4. Java中的权限修饰符(protected)示例详解

    前言大部分来自:https://blog.csdn.net/justloveyou_/article/details......

  5. MySQL修改字符集的实战教程

    前言:在 MySQL 中,系统支持诸多字符集,不同字符集之间也略有区别。目前最常用的字符集应该是 utf8 和 ut......

  6. Android 代码规范大全

    前言虽然我们项目的代码时间并不长,也没经过太多人手,但代码的规范性依然堪忧,目前存在较多的比较自由的「代码规范」,这......

  7. C# 合并和拆分PDF文件

    一、合并和拆分PDF文件的方式 PDF文件使用了工业标准的压缩算法,易于传输与储存。它还是页独立的,一个PDF文件包......

  8. 使用C#实现数据结构堆

    一、 堆的介绍: 堆是用来排序的,通常是一个可以被看做一棵树的数组对象。堆满足已下特性: 1. 堆中某个......

  9. Java多线程总结(二)

    四.Java多线程的阻塞状态与线程控制上文已经提到Java阻塞的几种具体类型。下面分别看下引起Java线程阻塞的主要......

  10. JavaScript 如何禁止用户保存图片

    场景 在业务需求中不希望用户保存图片,因为是一些供内部使用的图片。 思路 添加事件禁止选择、拖拽、右键(简单的禁......