Proxy
数据代理
两个参数
let obj = new Proxy(target,handler)
target 目标对象 我们需要处理的对象
handler 容器 无数可以处理对象属性的方法
自定义获取对象属性的获取 赋值 枚举 函数调用等功能
var target = {
a: 1,
b: 2,
};
let proxy = new Proxy(target, {
get(target, prop) {
console.log('This is property value' + target[prop]);
},
set() {},
});
console.log(proxy.a);
var target = {
a: 1,
b: 2,
};
let proxy = new Proxy(target, {
get(target, prop) {
return 'This is property value' + target[prop];
},
set(target, prop, value) {
target[prop] = value;
console.log(target[prop]);
},
});
console.log(proxy.a);
proxy.b = 3;
let target = {
a: 1,
b: 2,
};
let proxy = new Proxy(target, {
get(target, prop) {
return Reflect.get(target, prop);
},
set(target, prop, value) {
target[prop] = value;
},
has(target, prop) {
console.log(target[prop]);
},
deleteProperty(target, prop) {
delete target[prop];
},
});
console.log('a' in proxy);
console.log(proxy);
let target = {
a: 1,
b: 2,
};
let proxy = new Proxy(target, {
get(target, prop) {
return Reflect.get(target, prop);
},
set(target, prop, value) {
target[prop] = value;
},
has(target, prop) {
console.log(target[prop]);
},
deleteProperty(target, prop) {
delete target[prop];
},
});
delete proxy.b;
console.log(proxy);
操作数组
let arr = [
{ name: '小明', age: 18 },
{ name: '小红', age: 23 },
{ name: '小青', age: 14 },
{ name: '小黄', age: 35 },
{ name: '小王', age: 32 },
{ name: '小李', age: 40 },
];
let persons = new Proxy(arr, {
age(arr, prop) {
return arr[prop];
},
set(arr, prop, value) {
arr[prop] = value;
},
});
console.log(persons[3]);
persons[1] = { name: '小张', age: 33 };
console.log(persons);
操作函数
let fn = function () {
console.log('I am a function');
};
fn.a = 123;
let newFn = new Proxy(fn, {
get(fn, prop) {
return fn[prop] + ' This is a Proxy return';
},
});
console.log(newFn.a);
has不能拦截for in
has可以拦截in
let start = {
a: 'lisi',
b: 'zhangsan',
};
let agent = new Proxy(start, {
has: function (target, key) {
console.log('经过代理');
if (key === 'a') {
console.log('存在a');
return target[key];
}
},
});
console.log('a' in agent);
let start = {
a: 'lisi',
b: 'zhangsan',
};
let agent = new Proxy(start, {
has: function (target, key) {
console.log('经过代理');
if (key === 'a') {
console.log('存在a');
return target[key];
}
},
});
for (let key in agent) {
console.log(agent[key]);
}
对象操作的14种方法
1.获取原型[[GetPrototypeOf]]
var obj = { a: 1, b: 2 };
var proto = Object.getPrototypeOf(obj);
console.log(proto);
console.log(obj.__proto__);
console.log(Object.prototype);
2.设置原型[[SetPrototypeOf]]
var obj = { a: 1, b: 2 };
Object.setPrototypeOf(obj, { c: 3, d: 4 });
console.log(obj);
或者通过 obj.proto= 去赋值
var obj = { a: 1, b: 2 };
// Object.setPrototypeOf(obj, { c: 3, d: 4 });
obj.__proto__ = { e: 5, f: 6 };
console.log(obj);
3.获取对象的可扩展性[[IsExtensible]]
返回一个布尔值
var obj = { a: 1, b: 2 };
var extensible = Object.isExtensible(obj);
console.log(extensible);
冻结后不可扩展
var obj = { a: 1, b: 2 };
var extensible = Object.isExtensible(obj);
console.log(extensible);
Object.freeze(obj);
var extensible2 = Object.isExtensible(obj);
console.log(extensible2);
Object.seal
封闭对象
不可修改
不可删除
可写
可读(可枚举)
var obj = { a: 1, b: 2 };
Object.seal(obj);
obj.c = 3;
console.log(obj);
delete obj.a;
console.log(obj);
obj.b = 3;
console.log(obj);
for (var key in obj) {
console.log(obj[key]);
}
Object.freeze
冻结对象
不可修改
不可删除
不可写
可读(可枚举)
var obj = { a: 1, b: 2 };
Object.freeze(obj);
obj.c = 3;
console.log(obj);
delete obj.a;
console.log(obj);
obj.b = 3;
console.log(obj);
for (var key in obj) {
console.log(obj[key]);
}
4.获取自有属性[[GetOwnProperty]]
var obj = { a: 1, b: 2 };
Object.setPrototypeOf(obj, { c: 3, d: 4 });
console.log(Object.getOwnPropertyNames(obj));
5.禁止扩展对象[[PreventExtensions]]
禁止增加属性
var obj = { a: 1, b: 2 };
Object.preventExtensions(obj);
obj.c = 3;
console.log(obj);
可删除属性
var obj = { a: 1, b: 2 };
Object.preventExtensions(obj);
obj.c = 3;
console.log(obj);
delete obj.a;
console.log(obj);
6.拦截对象操作[[DefineOwnProperty]]
Object.defineProperty
前文已经描述过
7.判断是否是自身属性[[HasOwnProperty]]
var obj = { a: 1, b: 2 };
console.log(obj.hasOwnProperty('a'));
8. [[Get]]
var obj = { a: 1, b: 2 };
console.log('a' in obj);
console.log(obj.a);
9. [[Set]]
var obj = { a: 1, b: 2 };
obj.a = 3;
obj['b'] = 4;
console.log(obj);
10.[[Delete]]
var obj = { a: 1, b: 2 };
delete obj.a;
console.log(obj);
11.枚举[[Enumerate]]
var obj = { a: 1, b: 2 };
for (var k in obj) {
console.log(obj[k]);
}
12. 获取键集合 [[OwnPropertyKeys]]
var obj = { a: 1, b: 2 };
console.log(Object.keys(obj));
13.调用函数
var obj = { a: 1, b: 2 };
function test() {}
test();
test.call()
test.apply()
...
obj.test = function () {};
obj.test();
14.实例化的过程
function Test() {};
new Test(};
实现MyProxy
使用深拷贝与defineProperty实现一个简易的MyProxy
let target = {
a: 1,
b: 2,
};
function MyProxy(target, handler) {
let _target = deepClone(target);
Object.keys(_target).forEach((key) => {
Object.defineProperty(_target, key, {
get() {
return handler.get && handler.get(target, key);
},
set(newValue) {
handler.set && handler.set(target, key, newValue);
},
});
});
function deepClone(org, tar) {
var tar = tar || {},
toStr = Object.prototype.toString,
arrType = '[object Array]';
for (var key in org) {
if (org.hasOwnProperty(key)) {
if (typeof org[key] === 'object' && org[key] !== null) {
tar[key] = toStr.call(org[key]) === arrType ? [] : {};
deepClone(org[key], tar[key]);
} else {
tar[key] = org[key];
}
}
}
return tar;
}
return _target;
}
let proxy = new MyProxy(target, {
get(target, prop) {
return 'Get:' + prop + '=' + target[prop];
},
set(target, prop, value) {
target[prop] = value;
console.log('SET' + prop + '=' + value);
},
});
console.log(proxy.a);
proxy.b = 4;
console.log(proxy.b);
Reflect
反射 方法的集合 全局下的对象 有对象操作的13种方法 除了枚举
Reflect.get Reflect.set 返回布尔值