把原始数据作为属性值传入新对象中,发生原始数据修改丢失的问题怎么办?
- 应该使用Object.defineProperty()设置该属性
- 用Object.defineProperty()设置的属性,默认writable、enumerable、configurable均为false
- 并且自定义提醒该属性设置了不可重写
let obj = {
	a: 1
};
for (const key in obj) {
	console.log(key);
}
let keys = Object.keys(obj);
console.log(keys);
let desc = Object.getOwnPropertyDescriptor(obj, 'a');
console.log(desc);描述a:
值为1,可重写,可遍历
得到属性描述符
Object.getOwnPropertyDescriptor(obj, 'a');
重设属性描述符
Object.defineProperty(obj, 'a', { })
value: 23, //内容
writable: false, //不可重写
enumerable: false, //不可遍历
configurable: false //属性描述符本身可不可以重复修改
// 重新设置属性描述符
Object.defineProperty(obj, 'a', {
	value: 23,
	writable: false, //不可重写
	enumerable: false, //不可遍历
	configurable: false //属性描述符本身可不可以重复修改
}) 
/* 以下是无效的修改,因为上面的configurable: false */
Object.defineProperty(obj, 'a', {
	value: 23,
	writable: false, //不可重写
}) 
obj.a = 10;
console.log(obj.a);getter读取器
读取属性值
setter设置器
属性值重新赋值,有一个形参
合称访问器
设置了get和set函数后,将来读取这个属性时,他不会去内存中找,而是运行get函数
get函数里是什么,属性值输出就是什么
利用set函数限定原始数据的属性不可重写
let obj = {
	pic: './assets/g1.png',
	title: '椰云拿铁',
	desc: `1人份【年度重磅,一口吞云】`,
	choose: 0,
	sellNumber: 200,
	favorRate: 95,
	price: 32,
}
class UIGoods {
	constructor(g) {
		// this.data = g;
		Object.defineProperty(this, 'data', {
			get: function () {
				return g;
			},
			set: function () {
				throw new Error('data属性时是只读的,不能赋值和修改!')
			},
			configurable: false,
		})
	}
}
const g = new UIGoods(obj);
g.data = 'ab';
console.log(g.data);
利用set函数限定数值类型的属性,设置中间变量,判断它的值和类型
let internalChooseValue = 0;
Object.defineProperty(this, 'choose', {
	get: function () {
		return internalChooseValue;
	},
	set: function (val) {
		if (typeof val !== 'number') {
			throw new Error(`choose属性必须是数字!`);
		}
		let temp = parseInt(val);
		if (temp !== val) {
			throw new Error(`choose属性必须是整数!`);
		}
		if(val < 0) {
			throw new Error(`choose属性必须大于等于0!`);
		}
		internalChooseValue = val;
	},
	configurable: false
})利用get函数限定总价
Object.defineProperty(this, 'totalPrice', {
	get: function () {
		return this.choose * this.data.price;
	}
})er6语法糖简写,和constructor同级
get totalPrice () {
	return this.choose * this.data.price;
}利用get函数限定设置isChoose
get isChoose () {
	return this.choose > 0;
}Object.freeze()冻结原始数据的克隆版,让它的属性值也不能修改
尽量不要直接修改原始数据

避免新加属性进去 Object.freeze(this);
在最后冻结自己,可以防止新加属性改变数据,但是其他普通属性就不能改了

要使其他普通属性可修改,将freeze换成seal
这样使其他普通属性可修改,原始数据不可修改

限制不能在原型上添加属性














![[230609] 阅读TPO57汇总|9:30-10:50](https://img-blog.csdnimg.cn/9c0a245075634312bcc3f25456bcf45a.png)




