看完练习视频很自信的就开始编码了,由原来的代理碰到var、let作用域去了
还挺有意思的
let data = { name: "lin", age: 23 };
let _proxy = {};
//让proxy也有data的属性
// _proxy.name = data.name;//赋值操作,当data的name改变时,proxy是不会改变的
//主要原理通过Object.defineProperty
// Object.defineProperty(_proxy, "name", { value: "lus", writable: false });//不能重新定义name
//参数一是作用对象 参数二是作用的属性 参数三是属性描述对象
// console.log(_proxy.name); //lus
//writable为不可修改
// _proxy.name = "lili";
// console.log(_proxy.name); //lus
//循环遍历添加data属性
//我直接就key in data 大意了
for (var key in data) {
// console.log(key);
Object.defineProperty(_proxy, key, {
// get: function () {
// return data[key];
// },
//get()并没有任何参数,但是会传入this,但是这时的this不一定指向该属性的对象
// get: function (keyValue) {
// return data[keyValue];
// },
get: function () {
// console.log(this);//{name:<accessor>,age:<accessor>} accessor=>存取器,访问器
// console.log(this.name);//死循环,在get里面用get 那我方括号访问
// console.log(this["name"]);//emmm好吧,方括号也起get作用
console.log(key); //age 用var定义会是age let定义是name,age
return data[key];
},
// get() {
// return data[key];
// },
});
}
// console.log("我是循环外的", key);
console.log(_proxy.age);
console.log(_proxy["name"]); //为什么返回的age的值??? 原因竟是我for循环没用let定义key 那是不是说明用的是var?? 果然是var定义出现这问题
console.log(_proxy.name);
啊多么痛的领悟,是作用域的问题吧
就是var可以在外部调用 所以引用时其实是用的循环后的key值,也就是age
就说明get方法中key是获取的for循环里的key?
之后去浅看别人的数据劫持代理原理:是通过将属性值作为参数传入
//将属性值作为参数传入
function proxyObj(obj, key, value) {
Object.defineProperty(obj, key, {
get() {
console.log(`调用了get()获取属性${key}`);
return value;
},
});
}
let obj = { name: "张三", age: 33 };
// let keyArr = Object.keys(obj);//返回可枚举属性
// console.log(keyArr);
Object.keys(obj).forEach((key) => {
var value = obj[key];
proxyObj(obj, key, value);
});
console.log("函数式数据挟持代理:", obj.name);
还能通过递归写深层代理
//深层代理
function deepProxyObj(obj, key, val) {
Object.defineProperty(obj, key, {
get() {
console.log("调用了get()方法:获取" + key + "属性");
return val;
},
});
if (val instanceof Object) {
Object.keys(val).forEach((key) => {
deepProxyObj(val, key, val[key]);
});
}
}
let testObj = {
name: "李四",
age: 32,
cat: { name: "小咪", age: 3, color: "black" },
};
Object.keys(testObj).forEach((key) => {
deepProxyObj(testObj, key, testObj[key]);
});
console.log("深度代理:", testObj.cat.name);