IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> JavaScript知识库 -> JavaScript锁定对象的3种方法 -> 正文阅读

[JavaScript知识库]JavaScript锁定对象的3种方法

在 JavaScript 中,有时候需要锁定一个对象,有三个方法可供选择:

  1. Object.freeze

    • 不能新增属性
    • 不能修改属性
    • 不能修改已有属性的可枚举性、可配置性、可写性
    • 不能删除属性
  2. Object.seal

    • 不能新增属性
    • 不能修改已有属性的可枚举性、可配置性、可写性
    • 可以修改属性
    • 不能删除属性
  3. Object.preventExtensions

  • 不能新增属性

可以用下面的方法判断是否被冻结、是否密封和是否可拓展:

  • Object.isFrozen(myObj)
  • Object.isSealed(myObj)
  • Object.isExtensible(myObj)

如果想要深度冻结一个对象,可以用 deep-freeze 包,提供了下面的函数:

function deepFreeze (o) {
  Object.freeze(o)
  Object.getOwnPropertyNames(o).forEach(function (prop) {
    if (o.hasOwnProperty(prop)
    && o[prop] !== null
    && (typeof o[prop] === "object" || typeof o[prop] === "function")
    && !Object.isFrozen(o[prop])) {
      deepFreeze(o[prop])
    }
  })
  return o
}

深度剖析锁定后的对象

我们可以利用 Object.defineProperty 方法来分析被锁定的对象,该方法会直接在一个对象上定义一个新属性,或者修改一个对象的现有属性,并返回此对象,例如:

var obj = {}
Object.defineProperty(obj, 'name', {
  value: 'keliq'
})
console.log(obj)

可以看到,该方法有三个参数,分别是:

  • obj:要定义属性的对象
  • propName:属性名称
  • descriptor:属性描述符

前两个参数非常好理解,关键是第三个参数,是一个包含如下两个属性的对象:

  • enumerable:可枚举性,默认 false,表示不可以被 for-in 或 Object.keys() 遍历到。
  • configurable:可配置性,默认 false,表示属性不可枚举、不可写、不可删除和不可配置。

除此之外,还有四个可选属性:

  • value:属性对应的值,默认 undefined
  • writable:能否被赋值运算符改变,默认 false
  • get:属性的 getter 函数,默认 undefined
  • set:属性的 setter 函数,默认 undefined

但是,上面四个属性前两个和后两个是互斥的,即 valuewritable 不能和 getset 同时存在,要么设置 valuewritable,要么设置 getset。如果设置了前两个,我们称之为数据描述符,如果设置了后两个,我们称之为存取描述符,可以用下面这个表格来描述:

configurableenumerablevaluewritablegetset
数据描述符??????
存取描述符??????

讲了这么多,你可能还是云里雾里,我们从创建一个普通的对象开始看:

var obj = {name: 'keliq'}
console.log(Object.getOwnPropertyDescriptors(obj))

得到的结果为:

{
  name: {
    value: 'keliq',
    writable: true,
    enumerable: true,
    configurable: true
  }
}

也就是说 var obj = {name: 'keliq'} 等价于下面的代码:

var obj = {}
Object.defineProperty(obj, 'name', {
  value: 'keliq',
  writable: true,
  enumerable: true,
  configurable: true
})

如果我们只设置 value 会是什么效果呢?

var obj = {}
Object.defineProperty(obj, 'name', {
  value: 'keliq',
})
console.log(Object.getOwnPropertyDescriptors(obj))

结果是:

{
  name: {
    value: 'keliq',
    writable: false,
    enumerable: false,
    configurable: false
  }
}

嗯,可以看出来区别了。接下来,我们看 Object.seal 作用在对象上会怎样:

var obj = {name: 'keliq'}
Object.seal(obj)
console.log(Object.getOwnPropertyDescriptors(obj))

结果是:

{
  name: {
    value: 'keliq',
    writable: true,
    enumerable: true,
    configurable: false
  }
}

这下就比较清晰了,也可以顺理成章地解释为何 sealed 对象有以下特点:

  • 不能新增属性
  • 不能修改已有属性的可枚举性、可配置性、可写性
  • 可以修改属性
  • 不能删除属性

再看 Object.freeze 的效果:

var obj = {name: 'keliq'}
Object.seal(obj)
console.log(Object.getOwnPropertyDescriptors(obj))

结果是:

{
  name: {
    value: 'keliq',
    writable: false,
    enumerable: true,
    configurable: false
  }
}

可以看到,连 writable 都设置为 false 了,基本上这个对象被真的「冻住了」:

  • 不能新增属性
  • 不能修改属性
  • 不能修改已有属性的可枚举性、可配置性、可写性
  • 不能删除属性

最后看下 Object.preventExtensions 方法的效果:

var obj = {name: 'keliq'}
Object.preventExtensions(obj)
console.log(Object.getOwnPropertyDescriptors(obj))

结果是:

{
  name: {
    value: 'keliq',
    writable: true,
    enumerable: true,
    configurable: true
  }
}

这个结果和直接定义一个普通对象 var obj = {} 得到的属性描述符是一样的,并不能看出来其特殊之处,只有当添加新属性的时候,才能发现并不奏效:

var obj = {name: 'keliq'}
Object.preventExtensions(obj)
obj.name = 'david'
obj.age = 12
console.log(obj) // { name: 'david' }
  JavaScript知识库 最新文章
ES6的相关知识点
react 函数式组件 & react其他一些总结
Vue基础超详细
前端JS也可以连点成线(Vue中运用 AntVG6)
Vue事件处理的基本使用
Vue后台项目的记录 (一)
前后端分离vue跨域,devServer配置proxy代理
TypeScript
初识vuex
vue项目安装包指令收集
上一篇文章      下一篇文章      查看所有文章
加:2021-09-06 11:05:01  更:2021-09-06 11:05:39 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/23 16:58:19-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码