对象增强
- 属性描述符对属性进行比较精准的操作控制
- 通过属性描述符可以精准的添加或者修改对象的属性;
- 属性描述符需要使用Object.defineProperty来对属性进行添加或者修改;
- Object.defineProperty()方法会直接定义一个新属性,或者修改一个对象现有的1属性,并返回此对象
- Object.defineProperty(obj,prop,descriptor)
- obj都要定义属性的对象
- prop要定义或修改的属性的名称或Symbol;
- descriptor要定义或修改的属性描述符(这里是个对象);
-
const obj = { name: "小明", age: 16, }; Object.defineProperty(obj, "name", { configurable: false, //设置name属性,不可以被删除默认是true enumerable: false, //设置name属性,不可以被遍历。 writable: false, //设置name属性,不可以被修改 value: 12, //之前有值则修改name的值,没有则返回这个值 set//修改属性时会执行的函数。默认为undefind get//获取属性时会执行的函数。默认为undefind set(value) {//value是修改后的值 //只要修改name值就会监听 console.log("set方法被调用了", value); }, get() { //只要调用name值就会监听 console.log("get方法被调用了"); return "调用了"; }, }); // delete obj.name; obj.name = 12; console.log(obj.name);
- 返回值:被传递给函数的对象
- Object.defineProperties()方法直接在一个对象上定义多个新的属性或修改现有属性,并且返回该对象
-
const obj = { name: "小明", age: 16, }; Object.defineProperties(obj, { name: { configurable: false, enumerable: true, writable: false, }, age: { configurable: false, enumerable: false, },
- getOwnPropertyDescriptor
- getOwnPropertyDescriptors
-
1 const obj = { 2 name: "小明", 3 age: 16, 4 }; 5 Object.preventExtensions(obj); //阻止对象添加新的属性; 6 obj.skill = "biubiub"; //添加新属性,严格模式下会报错 7 console.log(obj); //新属性添加失败
- 密封对象:不允许配置和删除,可以修改原有的属性Object.seal(obj);
-
const obj = { name: "小明", age: 16, }; Object.seal(obj); //不允许更改 delete obj.name; obj.skill = "biubiub"; console.log(obj);//未改变
-
- 冻结对象,不允许修改现有的属性:Object.freeae(obj);
一、proxy
- proxy的基本使用
- es5之前监听对象的相关操作是Object.defineProperty(),proxy是用来帮助创建一个代理的,es6之后监听对象的相关操作。那样可以先创建一个代理对象(proxy对象
- 之后对该对象的所有操作,都通过代理对象来完成,代理对象可以监听我们想要对原对象进行那些操作;
- 首先先new Proxy对象,并且传入需要侦听的对象以及一个处理对象,可以称之为handler;
- 然后直接对proxy代理操作,而不是原有对象,因为我们需要在handler里面进行侦听;
- proxy的set和get捕获器
- 如果想要监听某些具体的操作,那么就可以在handler中添加对应的捕捉器
- set和get分别对应的函数类型;
-
const obj = { name: "小明", age: 18, }; const objproxy = new Proxy(obj, { //创建new proxy代理 set: function (target, key, value) { console.log(`监听${key}`, value); target[key] = value; //2、通过代理改变name的值 }, }); objproxy.name = "小黄"; //1、通过代理改变name的值 console.log(objproxy.name);
-
- set函数有四个参数:
- target:目标对象(侦听的对象);
- property:将被设置的属性key;
- value:新的属性值;
- receiver:调用的代理对象;
- get函数有三个参数:
- target:目标对象(侦听的对象);
- property:将被设置的属性key;
- receiver:调用的代理对象;
二、reflect
- reflect也是es6新增的一个APi,它是一个对象,字面意思是反射
- 配合proxy使用,好处一:代理对象的目的:不在直接操作原来对象
- 好处二:reflect.set方法有返回boolean值,可以判断本次操作是否成功