浅谈JS如何实现真正的对象常量


Posted in Javascript onJune 25, 2017

前言

众所周知ES6新增的const关键字可以用来声明常量,但是它只对基本数据类型生效(Number、String、Boolean等),那如果我们想声明一个常量对象呢?该如何实现,Object内置对象早就替我们想到了,下面来具体看一下

正题

一、先来看一下const方式来声明基本类型常量

代码:

const name = 'jack'
 name = 'lucy'  // 修改name常量

运行结果:

浅谈JS如何实现真正的对象常量

可以看到,控制台报错了,所以基本类型常量一旦声明复制,就不能在被修改

二、再来用const方式来声明复杂类型常量(即对象常量)

代码:

const Obj = {
 name: 'jack'
}

Obj.name = 'lucy' // 修改属性
Obj.age = 23 // 扩展属性
console.log(Obj.name)
console.log(Obj.age)

delete Obj.age
console.log(Obj.age) // 删除属性

Obj = {

 name: 'sam'
}

运行结果:

浅谈JS如何实现真正的对象常量

结果表明:对象常量只是不允许修改引用地址,但是属性还是可以被修改、扩展和删除的

要想得到一个真正的对象常量,我们无非要做的就是以下三点:

1.对象的属性不得被扩展

2.对象的属性不得被删除
3.对象的属性不得被修改

(1) 首先,如何做的对象属性不会被扩展呢?我们可以用Object.preventExtensions方法做到这一点

代码:

var Obj = {
 name: 'jack'
}

Object.preventExtensions(Obj)

Obj.age = 23 // 扩展属性
console.log(Obj.age) // undefined(说明扩展失败了)

运行结果:

浅谈JS如何实现真正的对象常量

(2) 接着,扩展的问题解决了,那如何实现属性不会被删除呢?不必担心,我们有Object.seal方法,该方法不仅可以保证对象的属性不会被扩展,而且还能防止属性被删除

代码:

var Obj = {
 name: 'jack'
}

Object.seal(Obj)

Obj.age = 23 // 扩展属性
console.log(Obj.age) // undefined(说明扩展失败了)

delete Obj.name // 删除属性
console.log(Obj.name) // 'jack'(说明删除失败了)

运行结果:

浅谈JS如何实现真正的对象常量

(3) 扩展和删除的问题都已经得到了解决,就剩下属性不得被修改的问题了,那么我们清楚终极Boss:Object.freeze,它可以做的对象既不可被扩展和删除,而且还不被修改

代码:

var Obj = {
 name: 'jack'
}

Object.freeze(Obj)

Obj.age = 23 // 扩展属性
console.log(Obj.age) // undefined(说明扩展失败了)

delete Obj.name // 删除属性
console.log(Obj.name) // 'jack'(说明删除失败了)

Obj.name = 'lucy' // 修改属性
console.log(Obj.name) // 'jack'(说明修改失败)

运行截图:

浅谈JS如何实现真正的对象常量

/***************************分割线*******************************/

以上就是一步步的演示如何实现一个真正的对象常量,但是有如下两个问题:

1.如果我们调用了这三个方法中的任何一个,然后我们再去做它们所禁止的行为(preventExtensions禁止扩展属性,seal禁止删除属性,freeze禁止修改属性),那么,如果在严格模式下,程序会报错,所以我们要谨慎使用

2.Object.freeze虽然实现了真正的对象常量,但是它的一切操作只在顶级对象属性上生效,下面的代码说明了这一问题

代码:

var Obj = {
 name: 'jack',

 extraInfo: {


 age: 23

 }
}

Object.freeze(Obj)

Obj.extraInfo.age = 80
console.log(Obj.extraInfo.age)
// 80

运行截图:

浅谈JS如何实现真正的对象常量

所以要想真正实现常量对象,我们需要以树的形式把对象的子孙对象都freeze,Object.freeze和递归可以解决该问题

// constantize实现递归freeze
var constantize = (obj) => {
 Object.freeze(obj);

 Object.keys(obj).forEach( (key, i) => {

 
 if ( typeof obj[key] === 'object' ) {

 
 
constantize( obj[key] );


 }

 });
}

var Obj = {

 name: 'jack',

 extraInfo: {

 
 age: 23

 }
}

constantize(Obj)

Obj.extraInfo.age = 80
console.log(Obj.extraInfo.age)  // 23

结语

以上就是常量对象的一些知识点,日常开发中,我们可以引入对象常量这个概念,来配置默认参数对象或一些配置信息,使我们的代码更加严谨

这篇浅谈JS如何实现真正的对象常量就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持三水点靠木。

Javascript 相关文章推荐
Underscore.js常用方法总结
Feb 28 Javascript
javascript简单进制转换实现方法
Nov 24 Javascript
微信小程序 require机制详解及实例代码
Dec 14 Javascript
Bootstrap的基本应用要点浅析
Dec 19 Javascript
jQuery实现页面顶部下拉广告
Dec 30 Javascript
详解ES6之async+await 同步/异步方案
Sep 19 Javascript
bootstrap 通过加减按钮实现输入框组功能
Nov 15 Javascript
JavaScript引用类型之基本包装类型实例分析【Boolean、Number和String】
Aug 09 Javascript
深入理解Vue父子组件生命周期执行顺序及钩子函数
Aug 12 Javascript
Vue和React组件之间的传值方式详解
Jan 31 Javascript
vue实现一个矩形标记区域(rectangle marker)的方法
Oct 28 Javascript
vue下拉刷新组件的开发及slot的使用详解
Dec 23 Vue.js
Easyui ueditor 整合解决不能编辑的问题(推荐)
Jun 25 #Javascript
解决JS内存泄露之js对象和dom对象互相引用问题
Jun 25 #Javascript
jQuery实现拖动效果的实例代码
Jun 25 #jQuery
JS检测window.open打开的窗口是否关闭
Jun 25 #Javascript
jQuery validata插件实现方法
Jun 25 #jQuery
简单谈谈axios中的get,post方法
Jun 25 #Javascript
jQuery鼠标移动图片上实现放大效果
Jun 25 #jQuery
You might like
CodeIgniter上传图片成功的全部过程分享
2013/08/12 PHP
PHP实现将浏览历史页面网址保存到cookie的方法
2015/01/26 PHP
PHP生成器简单实例
2015/05/13 PHP
php判断是否连接上网络的方法实例详解
2016/12/14 PHP
PHP开发之归档格式phar文件概念与用法详解【创建,使用,解包还原提取】
2017/11/17 PHP
php实现生成带二维码图片并强制下载功能
2018/02/24 PHP
浅谈laravel 5.6 安装 windows上使用composer的安装过程
2019/10/18 PHP
ASP Json Parser修正版
2009/12/06 Javascript
javascript获取ckeditor编辑器的值(实现代码)
2013/11/18 Javascript
HTML页面弹出居中可拖拽的自定义窗口层
2014/05/07 Javascript
jQuery ui 利用 datepicker插件实现开始日期(minDate)和结束日期(maxDate)
2014/05/22 Javascript
javascript实现多栏闭合展开式广告位菜单效果实例
2015/08/05 Javascript
javascript实现状态栏中文字动态显示的方法
2015/10/20 Javascript
学习JavaScript设计模式(策略模式)
2015/11/26 Javascript
Bootstrap弹出框modal上层的输入框不能获得焦点问题的解决方法
2016/12/13 Javascript
基于cookie实现zTree树刷新后展开状态不变
2017/02/28 Javascript
nodejs中向HTTP响应传送进程的输出
2017/03/19 NodeJs
jQuery插件HighCharts绘制简单2D柱状图效果示例【附demo源码】
2017/03/21 jQuery
带你快速理解javascript中的事件模型
2017/08/14 Javascript
详解ECMAScript typeof用法
2018/07/25 Javascript
详解JavaScript对数组操作(添加/删除/截取/排序/倒序)
2019/04/28 Javascript
如何利用JS将手机号中间四位变成*号
2020/09/29 Javascript
Python标准库之随机数 (math包、random包)介绍
2014/11/25 Python
python分析nignx访问日志脚本分享
2015/02/26 Python
利用python循环创建多个文件的方法
2018/10/25 Python
python对于requests的封装方法详解
2019/01/03 Python
基于OpenCV python3实现证件照换背景的方法
2019/03/22 Python
flask的orm框架SQLAlchemy查询实现解析
2019/12/12 Python
解决PDF 转图片时丢文字的一种可能方式
2021/03/04 Python
HTML5新特性 多线程(Worker SharedWorker)
2017/04/24 HTML / CSS
加州风格的游泳和沙滩装品牌:Cupshe
2019/06/10 全球购物
岗位职责风险点
2014/03/12 职场文书
毕业自我鉴定总结
2014/03/24 职场文书
村干部承诺书
2014/03/28 职场文书
向国旗敬礼活动总结
2014/09/27 职场文书
美丽心灵观后感
2015/06/01 职场文书