当前位置: 首页 > Web前端 > HTML5

JSES5也可以创建常量吗?

时间:2023-04-06 00:09:36 HTML5

本文介绍点赞+关注+书签=学过ES6刚推出的时候,let和const应该是大部分人学习ES6的第一个知识点。其中const可以用来定义常量,将不需要改变的数据定义为常量。但其实在ES6之前,我们也有定义常量的方法。ES5创建常量Object.defineProperty的基本用法在ES6之前不是const。如果需要定义常量,可以使用Object.defineProperty。很多人知道Vue2使用Object.defineProperty来监听数据变化,但不一定知道Object.defineProperty也可以用来定义常量。Object.defineProperty方法直接在一个对象上定义一个新的属性,或者修改一个对象已有的属性,并返回这个对象。Object.defineProperty(obj,prop,descriptor)接收3个参数obj:定义属性的对象。prop:要定义或修改的属性的名称或符号。描述符:要定义或修改的属性描述符。例如varLH={}Object.defineProperty(LH,'name',{value:'ThunderMonkey'})console.log(LH)//output:{name:'ThunderMonkey'}LH.name='SharkPepper'console.log(LH)//Output:{name:'ThunderMonkey'}你可以将上面的代码放到浏览器中试试看。为什么修改LH.name无效?因为descriptor除了value还有其他属性,比如writable可以用来定义对象是否允许修改,默认为false,即不可修改。所以LH.name='SharkPepper'修改没有效果。如果将writable改为true,可以修改varLH={}Object.defineProperty(LH,'name',{value:'ThunderMonkey',writable:true//允许修改})console.log(LH)//Output:{name:'ThunderMonkey'}LH.name='SharkPepper'console.log(LH)//Output:{name:'SharkPepper'}创建常量按照上面的思路,如果我们把LH改成window,可不可以在window上定义一个属性,而且这个属性是全局的,定义好之后可以在任何地方调用。Object.defineProperty(window,'NAME',{value:'Thundermonkey'})console.log(NAME)//输出:ThundermonkeyNAME='SharkPepper'console.log(NAME)//输出:Thundermonkeywindow.NAME='CockroachBully'console.log(NAME)//输出:无论迅雷猴怎么修改,NAME都是一开始定义的值。常量居然可以修改值?对于上面创建的常量,value是一个基本数据类型的值。如果替换为引用类型的值,则可以修改内容。Object.defineProperty(window,'NAME',{value:{nickname:'雷霆猴'}})console.log(NAME)NAME.nickname='SharkPepper'console.log(NAME)原因是常量锁is定义时指向的内存地址。在定义底层数据类型时,内存地址直接指向该值。但是在定义引用类型时,内存地址存放的是引用地址。所以常量的定义意味着引用地址不能被修改。兼容性使用Object.defineProperty定义常量时要注意兼容性