Object.defineProperty
方法创建属性并控制其行为。
Object.defineProperty
允许精确地定义对象的属性,通过属性描述符可以控制属性的可枚举性、可写性、可配置性等特性。Object.seal
方法锁定对象。
Object.seal
用于密封一个对象,这意味着不能向该对象添加新属性,并且现有属性的可配置性被设置为 false,即不能删除或重新配置现有属性。Object.freeze
方法冻结对象。
Object.freeze
会使对象完全不可变,不仅不能添加新属性、删除现有属性或重新配置现有属性,而且不能修改现有属性的值。综上所述,通过结合使用Object.defineProperty
、Object.seal
和Object.freeze
方法,可以实现对对象属性的精细控制和对象结构的严格锁定,以满足特定的编程需求。尤其是在需要确保数据的完整性和安全性的场景中,这些方法非常有用。
我们来看一段代码
/* 定义一个名为 aGoods 的对象 */
var aGoods = {
// 初始化 pic 属性为空字符串
pic: '',
// 初始化 title 属性为空字符串
title: '',
// 初始化 desc 属性为空字符串
desc: '',
// 初始化 sellNumber 属性为 1
sellNumber: 1,
// 初始化 favorTate 属性为 2
favorTate: 2,
// 初始化 price 属性为 3
price: 3,
};
// 定义 UiGoods 类
class UiGoods {
// 构造函数,接收一个参数 g
constructor(g) {
// 克隆 g 对象,确保 this.data 指向的是一个全新的对象,而非传入的 g 对象的引用
g = {...g}
// 冻结 g 对象,确保其属性不可被修改
Object.freeze(g);
// 定义 data 属性
// 配置属性描述符,设置 configurable 为 false,使得属性不可被删除或修改
Object.defineProperty(this, 'data', {
configurable: false,
// 定义 set 方法,当尝试修改属性值时,抛出错误
set: function () {
throw Error('不能修改');
},
// 定义 get 方法,访问属性时返回冻结的 g 对象,确保 data 属性不能被外部修改
get: function () {
return g;
}
});
// 定义 choose 属性
// 内部变量,初始化为 0
var internalChooseVal = 0;
// 配置 choose 属性描述符
Object.defineProperty(this, 'choose', {
configurable: false,
// 定义 getter,访问 choose 属性时返回 internalChooseVal
get: function () {
return internalChooseVal;
},
// 定义 setter,当设置 choose 属性时
set: function (v) {
// 确保输入为数字
if (typeof v!== 'number') {
throw Error('只能是数字');
}
// 确保值为整数且不小于 0
if (v < 0 || Math.floor(v)!== v) {
throw Error('只能是整数并且不能小于0');
}
// 设置 internalChooseVal 的值
internalChooseVal = v;
}
});
// 定义 totalPrice 属性
Object.defineProperty(this, 'totalPrice', {
// 配置 totalPrice 属性的 getter,计算 choose 属性和 data 属性中 price 值的乘积
get: function () {
return this.choose * this.data.price;
}
});
// 设置实例的 a 属性为 1
this.a = 1;
// 密封当前实例,使得其属性不可被删除,但属性值仍然可以被修改
Object.seal(this);
}
// 定义 isChoose 属性,检查 choose 属性是否大于 0
get isChoose() {
return this.choose > 0;
}
}
// 密封 UiGoods 类的原型,确保原型对象的属性和方法不能被修改或删除
Object.seal(UiGoods.prototype);
// 创建一个 UiGoods 实例
var g = new UiGoods(aGoods);
// 打印实例 g 的信息
console.log(g);
以下是代码中涉及到的知识点
对象创建和克隆
Object.defineProperty
对象封装
Error 抛出
数据计算
对象锁定
getter 方法