本文简介

点赞 + 关注 + 珍藏 = 学会了


ES6 刚推出的时候,letconst 应该是大多数人学习 ES6 的第一个知识点。

其中 const 能够用来定义 常量 ,将不须要扭转的数据定义成一个常量。

但其实在 ES6 之前咱们也是有方法定义常量的。



ES 5 创立常量

Object.defineProperty 的根底用法

ES6 之前是没有 const 的,如果须要定义常量,能够应用 Object.defineProperty

很多人晓得 Vue2 应用 Object.defineProperty 监听数据变动,但不肯定晓得 Object.defineProperty 也能够用来定义常量。


Object.defineProperty 办法会间接在一个对象上定义一个新属性,或者批改一个对象的现有属性,并返回此对象。

Object.defineProperty(obj, prop, descriptor) 接管3个参数

  • obj: 要定义属性的对象。
  • prop: 要定义或批改的属性的名称或 Symbol
  • descriptor: 要定义或批改的属性描述符。


举个例子

var LH = {}Object.defineProperty(LH, 'name', {  value: '雷猴'})console.log(LH) // 输入: {name: '雷猴'}LH.name = '鲨鱼辣椒'console.log(LH)  // 输入: {name: '雷猴'}

能够将下面的代码放到你的浏览器里试试。

为什么批改 LH.name 有效呢?因为 descriptor 除了 value 之外,还有其余属性,比方 writable 就能够用来定义该对象是否容许被批改,默认是 false ,也就是不能批改。

所以 LH.name = '鲨鱼辣椒' 批改有效。

如果将 writable 改成 true 就能够批改了

var LH = {}Object.defineProperty(LH, 'name', {  value: '雷猴',  writable: true // 容许批改})console.log(LH) // 输入: {name: '雷猴'}LH.name = '鲨鱼辣椒'console.log(LH)  // 输入: {name: '鲨鱼辣椒'}


创立常量

顺着下面的思路,如果咱们把 LH 改成 window ,那是不是就能够在 window 上定义一个属性,而且该属性是全局的,定义后在什么中央都能调用。


Object.defineProperty(window, 'NAME', {  value: '雷猴'})console.log(NAME) // 输入: 雷猴NAME = '鲨鱼辣椒'console.log(NAME) // 输入: 雷猴window.NAME = '蟑螂恶霸'console.log(NAME) // 输入: 雷猴

不论如何批改,NAME 都是最开始定义的值。



常量竟然能够批改值?

下面创立的常量,value 是一个根底数据类型的值。如果换成援用类型的值,那内容是能够批改的。

Object.defineProperty(window, 'NAME', {  value: {    nickname: '雷猴'  }})console.log(NAME)NAME.nickname = '鲨鱼辣椒'console.log(NAME)

起因是,常量锁定的是定义时所指向的内存地址。

定义根底数据类型时,内存地址间接指向那个值。但定义援用类型时,内存地址存的是援用地址。所以常量的定义指的是援用地址不能批改



兼容性

应用 Object.defineProperty 定义常量时须要留神兼容性



举荐浏览

《Object.defineProperty也能监听数组变动?》

《Vue3 过10种组件通信形式》

《console.log也能插图!!!》

《视差特效的原理和实现办法》


点赞 + 关注 + 珍藏 = 学会了

点赞 + 关注 + 珍藏 = 学会了