JS如何实现真正的对象常量
前言
众所周知ES6新增的const关键字可以用来声明常量,但是它只对基本数据类型生效(Number、String、Boolean等),那如果我们想声明一个常量对象呢?该如何实现,Object内置对象早就替我们想到了,下面来具体看一下
正题
一、先来看一下const方式来声明基本类型常量
代码:
const name = 'jack'
name = 'lucy' // 修改name常量
运行结果:

可以看到,控制台报错了,所以基本类型常量一旦声明复制,就不能在被修改
二、再来用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'
}
运行结果:

结果表明:对象常量只是不允许修改引用地址,但是属性还是可以被修改、扩展和删除的
要想得到一个真正的对象常量,我们无非要做的就是以下三点:
1.对象的属性不得被扩展
2.对象的属性不得被删除
3.对象的属性不得被修改
(1) 首先,如何做的对象属性不会被扩展呢?我们可以用Object.preventExtensions方法做到这一点
代码:
var Obj = {
name: 'jack'
}
Object.preventExtensions(Obj)
Obj.age = 23 // 扩展属性
console.log(Obj.age) // undefined(说明扩展失败了)
运行结果:

(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'(说明删除失败了)
运行结果:

(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'(说明修改失败)
运行截图:

/***************************分割线*******************************/
以上就是一步步的演示如何实现一个真正的对象常量,但是有如下两个问题:
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) //
运行截图:

所以要想真正实现常量对象,我们需要以树的形式把对象的子孙对象都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) //
结语
以上就是常量对象的一些知识点,日常开发中,我们可以引入对象常量这个概念,来配置默认参数对象或一些配置信息,使我们的代码更加严谨
JS如何实现真正的对象常量的更多相关文章
- JS 学习(四)对象
对象 在JS中,对象是数据(变量),拥有属性和方法. JS中所有事物都是对象:字符串.数字.数组.日期等. 对象是拥有属性和方法的特殊数据类型. 属性是与对象相关的值. 方法是能够在对象上执行的动作. ...
- js中内置有对象
statpot:使用mongo+bootstrap+highcharts做统计报表 最近做了一个统计项目,这个统计项目大致的需求是统计接口的访问速度.客户端会调用一个接口来记录接口的访问情况,我的需求 ...
- js 判断是否为空对象、空数组
当需要判断参数是否为空时,总希望 js 能够提供原生的判断方法,可惜并没有,只能自己封装了. function isEmpty(obj) { // 检验 undefined 和 null if(!ob ...
- jsp的C标签一般使用方法以及js接收servlet中的对象及对象数字
jsp的C标签一般使用方法以及js接收servlet中的对象及对象数组 由于现流行的javaWeb框架提倡前后端分离,比如在SpringMvc中已经很少写servlet的一些东西:目前 前端jsp中大 ...
- JS中的内置对象简介与简单的属性方法
JS中的数组: 1.数组的概念: 数组是在内存中连续存储的多个有序元素的结构,元素的顺序称为下标,通过下标查找对应元素 2.数组的声明: ①通过字面量声明var arr1 = [,,,,] JS中同一 ...
- JavaScript -- 时光流逝(六):js中的正则表达式 -- RegExp 对象
JavaScript -- 知识点回顾篇(六):js中的正则表达式 -- RegExp 对象 1. js正则表达式匹配字符之含义 查找以八进制数 规定的字符. 查找以十六进制数 规定 ...
- js基本类型存放和对象存放的区别(对象遍历)
js的基本类型,对象类型的应用在初学的时候,需要自己加以明确,明确了数据类型,在使用过程中才能正确使用变量.如下两个例子是摘自初学时的笔记,为大家提供参考. 1.对象可以存放属性和方法,js基本类型不 ...
- 关于js函数,方法,对象实例的一些说明
朋友们大家好,好久没有更新文章了,最近正好有空就想着写点什么吧,加上这段时间总是能听到一些朋友们问关于js函数,方法,对象实例到底有什么区别这个问题,所以今天就献丑来简单说明一些吧! 其实这些主要都是 ...
- js获取数组长度,对象成员个数字、符串字数
文章来源:百度文库 Javascript怎么得到数组长度(也就是数组的元素个数)? Javascript怎么获取对象的成员个数? 你肯定想到了array.length!? 那么我们来测试一下下面这 ...
随机推荐
- python object takes no parameters
class Song(object): def __init__(self,lyrics): self.lyrics = lyrics def sing_me_a_song(self): for li ...
- IOS的控制器
控制器简单来说,就是用来做界面跳转的,类似于 Android 的Intent 1.创建一个控制器 控制器的常见的创建方式 )通过storyboard创建 //直接创建 NJViewController ...
- 基于三层交换机和基于路由子接口的vlan间路由
1:通过三层交换机实现vlan间的通信:为三层交换机创建vlan,设置交换机的两个SVI,并配置IP地址. (在二层交换机上只能配置一个SVI端口,用来实现交换机交换机远程管理,在三层交换机上可以配置 ...
- winXP/win7/win10系统关闭445端口方法全攻略
近日有多个高校发布了关于连接校园网的电脑大面积中勒索病毒的消息,这种病毒致使许多高校毕业生的毕业论文(设计)被锁.受害机器的磁盘文件会被篡改为相应的后缀,图片.文档.视频.压缩包等各类资料都无法正常打 ...
- JAVA内存模型5-锁
锁的释放-获取建立的happens before关系 锁是java并发编程中最重要的同步机制.锁除了让临界区互斥执行外,还可以让释放锁的线程向获取同一个锁的线程发送消息.下面是锁释放-获 ...
- 【转】解决response.AddHeader("Content-Disposition", "attachment; fileName=" + fileName) 中文显示乱码
如果fileName为中文则乱码.解决办法是 方法1: response.setHeader("Content-Disposition", "attachment; fi ...
- OpenCV探索之路(三):滤波操作
滤波处理分为两大类:线性滤波和非线性滤波.OpenCV里有这些滤波的函数,使用起来非常方便,现在简单介绍其使用方法. 线性滤波:方框滤波.均值滤波.高斯滤波 方框滤波 #include<open ...
- 基于腾讯云的Centos6.2系统搭建Apache+Mysql+PHP开发环境
搭建环境,我肯定需要先购买腾讯云服务器的哦! 然后,我们打开SecureCRT 7.3,这是一款可以连接Linux系统的客户端工具,使用的很方便快捷,要注意的是,若你是Linux系统的就要用22端口, ...
- PHP是什么文件? 如何打开?
PHP是什么文件? PHP,一个嵌套的缩写名称,是英文"超级文本预处理语言"(PHP:Hypertext Preprocessor)的缩写.PHP 是一种 HTML 内嵌式的语言 ...
- PHP简单分页省略中间页码
<?php /** * @desc created by sublime text3 * @author jxl <[57953279@qq.com>]> * @since 2 ...