搞懂JavaScript中的防篡改对象

古之立大事者,不惟有超世之才,亦必有坚忍不拔之志。——苏轼

写在前面

我们在实际的开发中,可能需要自己封装 API ,如果供人使用的话,可能是禁止修改我们自己定义的对象的,JavaScript 中就给我们提供了这种防篡改机制。

防篡改是什么

定义的对象默认在任何时候、任何位置,无论有意义的还是无意义的都可以修改对象的属性或方法。而这些篡改可能会影响对象的内置属性或方法,从而导致对象的正常功能可能无法使用。 JavaScript 在 ECMAScript5 版本中新增了放置篡改对象的属性或方法的机制,共提供了以下三级保护方式:

  1. 禁止扩展: 禁止为对象扩展新的属性或方法
  2. 密封对象: 禁止扩展新的属性或方法,禁止配置现有的属性或方法的描述符,仅允许读写属性的值。
  3. 冻结对象: 禁止对对象执行任何修改操作。

值得注意的是,一旦定义了防篡改对象,就无法撤销了,也就是说无法改回了。

禁止扩展

所谓的禁止扩展,就是禁止为对象扩展新的属性或方法。

Object 对象提供的 preventExtensions() 方法让一个对象变的不可扩展,也就是永远不能再添加新的属性。

语法结构如下:

Object.preventExtensions(obj)

参数

  • obj: 将要变得不可扩展的对象。

返回值: 已经不可扩展的对象。

如果一个对象可以添加新的属性,则这个对象是可扩展的。Object.preventExtensions() 将对象标记为不再可扩展,这样它将永远不会具有它被标记为不可扩展时持有的属性之外的属性。注意,一般来说,不可扩展对象的属性可能仍然可被删除。尝试将新属性添加到不可扩展对象将静默失败或抛出 TypeError 异常。

示例代码如下

var obj = {}

// 将对象设置为禁止扩展
Object.preventExtensions(obj);

// 新增属性或方法无效,但是语法并不报错
obj.name = '涂山红红';
console.log(obj);
/*
  通过 Object.defineProperty() 方法新增属性
   * 抛出异常, 提示信息: TypeError: Cannot define property: name, object is not extensible.
*/
Object.defineProperty(obj, 'name', {
  value: '涂山雅雅'
});

Object 对象还提供了 isExtensible() 方法,此方法用于判断一个对象是否可扩展。

语法结构如下

Object.isExtensible(obj)

参数

obj:需要检测的对象

返回值:返回一个 Boolean 值,可扩展为 true,不可扩展为 false。

示例代码如下

console.log(Object.isExtensible()); 	// false

密封对象

所谓密封对象,就是指禁止扩展新的属性或方法,禁止配置现有的属性或方法的描述符(包括两种,一种是 writable 修改此描述符不会报错,但是会修改失败,另一种包括 configurable 和 enumerable 两个描述符,修改此描述符会报错)。

Object 对象提供的 seal() 方法用于封闭对象。语法结构如下

Object.seal(obj)

参数

  • obj: 将要密封的对象。

返回值: 已经密封的对象。

示例代码如下

var obj = {
  name: '涂山红红'
}
// 封闭对象
Object.seal(obj)
// 新增属性
obj.age = 18;
console.log(obj); // 无效,但是并不报错
console.log(Object.getOwnPropertyDescriptor(obj, 'name'));
// 修改属性描述符
Object.defineProperty(obj, 'name', {
  configurable: true // 抛出异常 TypeError: Cannot redefine property: name
})

Object 对象还提供了 isSealed() 方法,此方法用于判断一个对象是否可扩展。

语法结构如下

Object.isSealed(obj)	

参数

obj:需要检测的对象

返回值:返回一个 Boolean 值,已封闭为 true,否则为 false。

示例代码如下

console.log(Object.isSealed()); // true

冻结对象

所谓的冻结对象就是指禁止对对象进行任何操作。

Object.freeze() 方法可以冻结一个对象。一个被冻结的对象再也不能被修改;冻结了一个对象则不能向这个对象添加新的属性,不能删除已有属性,不能修改该对象已有属性的可枚举性、可配置性、可写性,以及不能修改已有属性的值。此外,冻结一个对象后该对象的原型也不能被修改。

语法结构如下:

Object.freeze(obj)

参数

  • obj:要被冻结的对象。

返回值

被冻结的对象。

示例代码如下

var obj = {
  name: '涂山红红'
}

// 冻结对象
Object.freeze(obj)
// 修改属性
obj.name = '涂山苏苏'
// 新增属性
obj.age = 18;


console.log(obj); // 无效,但是并不报错
// 修改属性描述符
Object.defineProperty(obj, 'name', {
  value: '小蠢货' // 抛出异常 TypeError: Cannot redefine property: name
})

Object 也提供了判断一个对象是佛冻结的方法,这个方法是 Object.isFrozen()

值得注意的是,一个冻结的对象既是一个密封对象,也是一个不可扩展对象。

示例代码如下:

console.log(Object.isFrozen()); // true
console.log(Object.isExtensible()); // false
console.log(Object.isSealed()); // true

写在最后

JavaScript 中的 Object 对象提供的方法可以帮助我们完成需要防止对象篡改的级别,保护了对象的安全。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

一碗周.

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值