资讯专栏INFORMATION COLUMN

如何在 ES5 环境下实现一个const ?

Muninn / 740人阅读

作者:陈大鱼头

github: KRISACHAN

前言

刚刚看了掘金上一篇文章《作为技术面试官,为什么把你pass了》,里面第一题就是用es5实现const,据作者反馈 这一题所有的面试者都没有回答出来,感觉挺可惜的,其实这是一道比较简单的题目,但是由于涉及到了一些Object对象属性描述符的知识,这些描述符往往用到的场景不多,所以不容易记住。

属性描述符: 对象里目前的属性描述符有两种:

数据描述符:具有值的属性

存取描述符:由getter与setter函数对描述的属性

描述符功能:

数据描述符与存取描述符皆可修改:

configurable:当前对象元素的属性描述符是否可改,是否可删除

enumerable:当前对象元素是否可枚举

唯有数据描述符可以修改:

value: 当前对象元素的值

writable:当前对象元素的值是否可修改

唯有存取描述符可以修改:

get:读取元素属性值时的操作

set:修改元素属性值时的操作

描述符可同时具有的键值:
configurable enumerable value writable get set
数据描述符 Yes Yes Yes Yes No No
存取描述符 Yes Yes No No Yes Yes
const 实现原理

由于ES5环境没有block的概念,所以是无法百分百实现const,只能是挂载到某个对象下,要么是全局的window,要么就是自定义一个object来当容器

      var __const = function __const (data, value) {
        window.data = value // 把要定义的data挂载到window下,并赋值value
        Object.defineProperty(window, data, { // 利用Object.defineProperty的能力劫持当前对象,并修改其属性描述符
          enumerable: false,
          configurable: false,
          get: function () {
            return value
          },
          set: function (data) {
            if (data !== value) { // 当要对当前属性进行赋值时,则抛出错误!
              throw new TypeError("Assignment to constant variable.")
            } else {
              return value
            }
          }
        })
      }
      __const("a", 10)
      console.log(a)
      delete a
      console.log(a)
      for (let item in window) { // 因为const定义的属性在global下也是不存在的,所以用到了enumerable: false来模拟这一功能
        if (item === "a") { // 因为不可枚举,所以不执行
          console.log(window[item])
        }
      }
      a = 20 // 报错
题外话

Vue目前双向绑定的核心实现思路就是利用Object.defineProperty对getset进行劫持,监听用户对属性进行调用以及赋值时的具体情况,从而实现的双向绑定~~



如果你、喜欢探讨技术,或者对本文有任何的意见或建议,你可以扫描下方二维码,关注微信公众号“鱼头的Web海洋”,随时与鱼头互动。欢迎!衷心希望可以遇见你。

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/6907.html

相关文章

  • ES5和ES6作用域详解

    摘要:允许在块级作用域内声明函数。上面代码中,存在全局变量,但是块级作用域内又声明了一个局部变量,导致后者绑定这个块级作用域,所以在声明变量前,对赋值会报错。 ES5的作用域 变量起作用的范围,js中能创建作用域的只能是函数 { let a = 1; var b = 2; } console.log(a); // a is not defined console.log(b); //...

    Dr_Noooo 评论0 收藏0
  • 面试官:自己搭建过vue开发环境吗?

    摘要:在搭建过程中,还是会踩很多坑的。如果还不熟悉的话,建议自己搭建一次。开篇 原文地址:www.ccode.live/lentoo/list… 前段时间,看到群里一些小伙伴面试的时候被面试官问到这类题目。平时大家开发vue项目的时候,相信大部分人都是使用 vue-cli脚手架生成的项目架构,然后 npm run install 安装依赖,npm run serve启动项目然后就开始写业务代码...

    HelKyle 评论0 收藏0
  • ES6核心特性

    摘要:报错不报此外还有个好处就是简化回调函数正常函数写法箭头函数写法改变指向长期以来,语言的对象一直是一个令人头痛的问题,在对象方法中使用,必须非常小心。 前言 ES6 虽提供了许多新特性,但我们实际工作中用到频率较高并不多,根据二八法则,我们应该用百分之八十的精力和时间,好好专研这百分之二十核心特性,将会收到事半功倍的奇效!写文章不容易,请大家多多支持与关注!本文首发地址GitHub博客(...

    loostudy 评论0 收藏0
  • ES6核心特性

    摘要:报错不报此外还有个好处就是简化回调函数正常函数写法箭头函数写法改变指向长期以来,语言的对象一直是一个令人头痛的问题,在对象方法中使用,必须非常小心。 前言 ES6 虽提供了许多新特性,但我们实际工作中用到频率较高并不多,根据二八法则,我们应该用百分之八十的精力和时间,好好专研这百分之二十核心特性,将会收到事半功倍的奇效!写文章不容易,请大家多多支持与关注!本文首发地址GitHub博客(...

    _DangJin 评论0 收藏0
  • ES6学习 第一章 let 和 const 命令

    摘要:外层作用域不报错正常输出块级作用域与函数声明规定,函数只能在顶层作用域和函数作用域之中声明,不能在块级作用域声明。规定,块级作用域之中,函数声明语句的行为类似于,在块级作用域之外不可引用。同时,函数声明还会提升到所在的块级作用域的头部。 前言:最近开始看阮一峰老师的《ECMAScript 6 入门》(以下简称原...

    番茄西红柿 评论0 收藏2637

发表评论

0条评论

最新活动
阅读需要支付1元查看
<