09-属性描述符Object.getOwnPropertyDescriptor(),原始数据不可重写

把原始数据作为属性值传入新对象中,发生原始数据修改丢失的问题怎么办?

  • 应该使用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函数里是什么,属性值输出就是什么

Object.defineProperty()定义的属性,属性值被修改时实际上在执行什么代码?

let obj = {};

Object.defineProperty(obj, 'a', {
	get: function () {
		console.log('hello');
		return 2
	},
	set: function (val) {
		console.log('你好');
	}
})
// obj.a = 10;
obj.a = 3 - 2; // set(3-2)
console.log(obj.a); // console.log(get())

输出结果:你好  hello  2

这里定义了一个空对象,用 defineProperty 定义了一个属性 a

obj.a = 3 - 2; 这句话意思是在重新赋值,所以属性值改变的时候,是调用set函数

console.log(obj.a); 得到属性 a 的值,其实就是读取属性值,调用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

这样使其他普通属性可修改,原始数据不可修改

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

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值