浅谈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 相关文章推荐
jQuery 解析xml文件
Aug 09 Javascript
javascript闭包入门示例
Apr 30 Javascript
avascript中的自执行匿名函数应用示例
Sep 15 Javascript
jQuery+PHP+MySQL实现无限级联下拉框效果
Feb 19 Javascript
jquery获取复选框checkbox的值实现方法
May 30 Javascript
Javascript缓存API
Jun 14 Javascript
vue Element-ui input 远程搜索与修改建议显示模版的示例代码
Oct 19 Javascript
其实你可以少写点if else与switch(推荐)
Jan 10 Javascript
使用vuepress搭建静态博客的示例代码
Feb 14 Javascript
vue实现多条件和模糊搜索功能
May 28 Javascript
微信小程序swiper实现文字纵向轮播提示效果
Jan 21 Javascript
详解Vue3 Teleport 的实践及原理
Dec 02 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
php中替换字符串函数strtr()和str_repalce()的用法与区别
2016/11/25 PHP
PHP房贷计算器实例代码,等额本息,等额本金
2017/04/01 PHP
[原创]php使用strpos判断字符串中数字类型子字符串出错的解决方法
2017/04/01 PHP
PHP工厂模式的日常使用
2019/03/20 PHP
javascript 动态加载 css 方法总结
2009/07/11 Javascript
JavaScript中链式调用之研习
2011/04/07 Javascript
javascript中比较字符串是否相等的方法
2013/07/23 Javascript
利用js读取动态网站从服务器端返回的数据
2014/02/10 Javascript
js中函数调用的两种常用方法使用介绍
2014/07/17 Javascript
js获取指定字符前/后的字符串简单实例
2016/10/27 Javascript
js+css实现红包雨效果
2018/07/12 Javascript
深入浅出理解JavaScript闭包的功能与用法
2018/08/01 Javascript
vue中的watch监听数据变化及watch中各属性的详解
2018/09/11 Javascript
微信小程序日历组件使用方法详解
2018/12/29 Javascript
JS实现二维数组元素的排列组合运算简单示例
2019/01/28 Javascript
自定义Vue中的v-module双向绑定的实现
2019/04/17 Javascript
javascript实现图片轮播代码
2019/07/09 Javascript
VueQuillEditor富文本上传图片(非base64)
2020/06/03 Javascript
vue中使用vue-pdf的方法详解
2020/09/05 Javascript
夯基础之手撕javascript继承详解
2020/11/09 Javascript
[46:00]Ti4 冒泡赛第二轮LGD vs C9 2
2014/07/14 DOTA
[54:45]2018DOTA2亚洲邀请赛 4.1 小组赛 A组 Optic vs OG
2018/04/02 DOTA
[44:33]EG vs Liquid 2018国际邀请赛小组赛BO2 第二场 8.18
2018/08/19 DOTA
Python读写Excel文件方法介绍
2014/11/22 Python
python基础教程项目三之万能的XML
2018/04/02 Python
手把手教你用纯css3实现轮播图效果实例
2017/05/04 HTML / CSS
钉钉企业内部H5微应用开发详解
2020/05/12 HTML / CSS
来自圣地亚哥的实惠太阳镜:Knockaround
2018/08/27 全球购物
美国购买舞会礼服网站:Couture Candy
2019/12/29 全球购物
Hashtable 添加内容的方式有哪几种,有什么区别?
2012/04/08 面试题
大学生的网络创业计划书
2013/12/26 职场文书
酒店保安员岗位职责
2014/01/31 职场文书
创先争优活动方案
2014/02/12 职场文书
疾病捐款倡议书
2014/05/13 职场文书
反邪教学习心得体会
2016/01/15 职场文书
2020年个人安全保证书参考模板
2020/01/08 职场文书