JS ES5也可以创建常量?🎃


theme: smartblue

持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第33天,点击查看活动详情


本文简介

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


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: 要定义或修改的属性描述符。


举个例子

  1. var LH = {}
  2. Object.defineProperty(LH, name, {
  3. value: 雷猴
  4. })
  5. console.log(LH) // 输出: {name: 雷猴}
  6. LH.name = 鲨鱼辣椒
  7. console.log(LH) // 输出: {name: 雷猴}

可以将上面的代码放到你的浏览器里试试。

为什么修改 LH.name 无效呢?因为 descriptor 除了 value 之外,还有其他属性,比如 writable 就可以用来定义该对象是否允许被修改,默认是 false ,也就是不能修改。

所以 LH.name = 鲨鱼辣椒 修改无效。

如果将 writable 改成 true 就可以修改了

  1. var LH = {}
  2. Object.defineProperty(LH, name, {
  3. value: 雷猴,
  4. writable: true // 允许修改
  5. })
  6. console.log(LH) // 输出: {name: 雷猴}
  7. LH.name = 鲨鱼辣椒
  8. console.log(LH) // 输出: {name: 鲨鱼辣椒}


创建常量

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


  1. Object.defineProperty(window, NAME, {
  2. value: 雷猴
  3. })
  4. console.log(NAME) // 输出: 雷猴
  5. NAME = 鲨鱼辣椒
  6. console.log(NAME) // 输出: 雷猴
  7. window.NAME = 蟑螂恶霸
  8. console.log(NAME) // 输出: 雷猴

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



常量居然可以修改值?

上面创建的常量,value 是一个基础数据类型的值。如果换成引用类型的值,那内容是可以修改的。

  1. Object.defineProperty(window, NAME, {
  2. value: {
  3. nickname: 雷猴
  4. }
  5. })
  6. console.log(NAME)
  7. NAME.nickname = 鲨鱼辣椒
  8. console.log(NAME)

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

定义基础数据类型时,内存地址直接指向那个值。但定义引用类型时,内存地址存的是引用地址。所以常量的定义指的是引用地址不能修改



兼容性

使用 Object.defineProperty 定义常量时需要注意兼容性

01.png



推荐阅读

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

👍《Vue3 过10种组件通讯方式》

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

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


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


文章标签:

原文连接:https://juejin.cn/post/7114909033626075144

相关推荐

Webpack学习系列 - Webpack5 怎么集成Babel ?

我在淘宝做弹窗,2022 年初的回顾与展望

看完这篇,你也可以搞定有趣的动态曲线绘制

低代码平台的属性面板该如何设计?

34个图片压缩工具集合,包含在线压缩和CLI工具

冴羽答读者问:过程比结果重要吗?如果是,怎么理解?如果不是,又怎么解?

中杯超大杯中间的新选择——vue2.7+vite+ts实践

LiveData源码分析

亚马逊Prime:流媒大战杀手锏

Vue详解知识概括

基于 Docker 来部署 Vue 或 React 前端项目及 Node 后端服务

完美解决自定义字体垂直方向上下偏移的问题

使用vuepress从零开始搭建我的技术文档|已部署到线上

【Vue.js 3.0源码】AST 转换之节点内部转换

小程序+电商,该如何寻找营销增长点

前端如何开始深度学习,那不妨试试JAX

你可能不知道的 前端浏览器(window) 对本地文件操作(File System Access API)

爱奇艺向抖音开启授权,打开内容价值的新大门

使用ComposeDesktop开发一款桌面端多功能APK工具

一个简洁、强大、可扩展的前端项目架构是什么样的?