Object.defineProperty
function myDefineProperty() {
var _obj = {};
// Object.defineProperty(_obj,'a',{value:1})
Object.defineProperties(_obj, {
a: {
value: 1,
writable: true, //可修改
enmuerable: true, //可枚举 遍历
configurable: true, //可配置,删除
//get: function () {}, //get set跟value writable互斥
//set: function (newVal) {},
},
});
return _obj;
}
var obj = myDefineProperty();
操作数组小例子
function DataArr() {
var _val = null;
var _arr = [];
Object.defineProperty(this, "val", {
get: function () {
return _val;
},
set: function (newVal) {
_val = newVal;
_arr.push({ val: _val });
},
});
this.getArr = function () {
return _arr;
};
}
var dataArr = new DataArr();
Proxy
其实就是 es6 里的一个构造函数
Proxy handler 重写 proxy 内部方法->转发给 target
而 defineProperty 劫持数据->给对象进行扩展->属性进行设置
defineProperty 数组 push 无法触发而 proxy 可以
var target = {
a: 1,
b: 2,
};
let proxy = new Proxy(target, {
get(target, prop) {
console.log(target[prop]);
},
set(target, prop, value) {
target[prop] = value;
},
});
手写 Proxy
function MyProxy(target, handler) {
let _target = deepClone(target);
console.log(_target);
Object.keys(_target).forEach((key) => {
Object.defineProperty(_target, key, {
get() {
return handler.get && handler.get(target, key);
},
set(newVal) {
handler.set && handler.set(target, key, newVal);
},
});
});
return _target;
function deepClone(target, newObj) {
let tempObj = newObj || {};
let toStr = Object.prototype.toString;
let arrType = "[Object Array]";
for (let key in target) {
if (target.hasOwnProperty(key)) {
if (typeof target[key] === "object" && target[key] !== null) {
if (toStr.call(target[key]) === arrType) {
tempObj[key] = [];
} else {
tempObj[key] = {};
}
deepClone(target[key], tempObj[key]);
} else {
tempObj[key] = target[key];
}
}
}
return tempObj;
}
}
const obj = { a: 1, b: 3, c: [1, 2, { c: 1 }] };
const myproxy = new MyProxy(obj, {
get(target, prop) {
return target[prop];
},
set(target, prop, val) {
target[prop] = val;
},
});
myproxy.a = 3;
console.log(myproxy);
Object 内建 14 种方法
- 获取原型
[[GetPrototypeOf]]//暴露出的api是 Object.getPrototypeOf(obj); obj.__proto__; Object.prototype; - 设置原型
[[SetPrototypeOf]]//暴露出的api是 Object.setPrototypeOf(obj, { a: 123 }); Object.prototype.a = 123; - 获取对象的可扩展性
[[IsExtensible]]//暴露出的api是 Object.isExtensible(obj); - 获取自有属性
[[GetOwnProperty]]//暴露出的api是 Object.getOwnPropertyNames(obj); - 禁止扩展对象
[[PreventExtensions]]//暴露出的api是 Object.preventExtensions(obj); - 拦截对象操作
[[DefineOwnProperty]]//暴露出的api是 Object.defineProperty(obj, a, handler); - 判断是否为自身属性
[[HasProperty]]//暴露出的api是 obj.hasOwnPropety("a"); [[GET]]//暴露出的api是 "a" in obj; obj.a;[[SET]][[DELETE]]- 枚举
[[Enumrate]]//暴露出的api是 for (var key in obj) { console.log(obj[key]); } - 获取键集合
[[OwnPropertyKeys]]//暴露出的api是 Object.keys(obj); - 调用函数的方法
- new 实例化操作