数据劫持方法
- 最近空余时间复习了下JavaScript;做为学习总结 !
1、对象内自带的set
和get
方法数据劫持、
//首先我们先定义一个对象
let obj = {
$name: "张三",
get name(){ // 获取 name 属性时触发
//console.log("想要获取name属性");
return this.$name;// 想要让 obj 在获取name 属性时,拿到的值
},
set name(newVal){ // 设置 name 属性时 触发
console.log(newVal); // 给 name 设置的新值
this.$name = newVal;
}
};
console.log(obj.name); //获取name值 (触发get方法)
obj.name = '我是李四'; //重新赋值(调取set方法)
//以上为对象赋值和获取数据的劫持方法
2、Object.defineProperty
数据劫持
let obj = {
name:"张三"
}
//对obj中的name进行数据劫持
Object.defineProperty(obj,"name",{
configurable: true, //配置是否允许被删除 true(默认值) 可以被删除,false 不能被删除
enumerable: true, //配置是否允许被枚举 true(默认值) 可以被枚举,false 不能被枚举
// ....以下有更多使用方法
//重新给obj中的name赋值时触发
set(newVal){
console.log("这个想要设置的新值",newVal);
},
//获取obj中的name值时触发
get(){
return '给你返回的名字';
}
});
obj.name = 'hello'; //赋值
let a = obj.name; //获取
console.log(a);
/*
以下为Object.defineProperty(obj, key, descriptor)的详细使用说明;
- obj 要在其上定义属性的对象。
- ley 要定义或修改的属性的名称。
- descriptor 将被定义或修改的属性描述符。
使用参数
- value 该属性对应的值。可以是任何有效的 JavaScript 值(数值,对象,函数等)。默认为 undefined。
- writable 当且仅当该属性的writable为true时,value才能被赋值运算符改变。默认为 true。
- 存取描述符
- get 一个给属性提供 getter 的方法,如果没有 getter 则为 undefined。当访问该属性时,该方法会被执行,方法执行时没有参数传入,但是会传入this对象(由于继承关系,这里的this并不一定是定义该属性的对象)。默认为 undefined。
- set 一个给属性提供 setter 的方法,如果没有 setter 则为 undefined。当属性值修改时,触发执行该方法。该方法将接受唯一参数,即该属性新的参数值。默认为 undefined。
*/
let obj = {
name:"hello"
}
/*
defineProperty 的默认值问题:
情况一,该属性已经在对象定义过:
configurable: true
enumerable: true
value: "hello"
writable: true
情况二,该属性在对象未定义过:
configurable: false
enumerable: false
value: undefined
writable: false
*/
Object.defineProperty(obj,"name",{
});
console.log(Object.getOwnPropertyDescriptor(obj,"name"));
/*
getOwnPropertyDescriptor 获取该对象相关的描述
*/
3、Object.defineProperties
let data = {
name: "hello",
age: 100
};
//当对对象中的多个值进行数据劫持时
//入参:obj对象、具体配置
Object.defineProperties(data,{
name:{
set(newVal){
console.log(newVal);
},
get(){
return "怎么好意思问人家的名字呀"
}
},
age: {
set(newVal){
console.log(newVal);
},
get(){
return "怎么好意思问人家的年龄呢"
}
}
});
console.log(data);
4、Proxy
//首先我们先定义对象
let data = {
name: "mt",
age: 8,
price: 9000
};
//let proxy = new Proxy(target, handler);
// target 是用Proxy包装的被代理对象(可以是任何类型的对象,包括原生数组,函数,甚至另一个代理)
// handler 是一个对象,其声明了代理target 的一些操作,其属性是当执行一个操作时定义代理的行为的函数。
let proxyData = new Proxy(data,{
// 方法用来处理获取数据时的劫持行为
get(target,key){
if(key == "price"){
return target[key]*.9;
}
return target[key];
},
// 方法用来处理设置数据时的劫持行为
set(target,key,newVal){
target[key] = newVal;
},
// 方法用来处理在判断是否有该属性时的劫持行为
has(target,key){ //判断某个值存不存
//return true 存在该属性,false 不存在该属性
if(key == "gf"){
return true;
}
return (key in target);
}
});
console.log(proxyData);
// console.log(proxyData.price);
// console.log(proxyData.age);
/*
Proxy.get 在对数据进行获取操作的时候,进行拦截
*/
// proxyData.price = 600;
// proxyData.price = 700;
![在这里插入图片描述](https://img-blog.csdnimg.cn/20210326204911535.jpeg?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl80MzE0MDMwMA==,size_14,color_FFFFFF,t_70#pic_center)