Object.defineProperty()
给一个对象设置新的属性,或者修改属性。
兼容性:
IE9+,IE8中只能用在DOM对象上。
用法:
Object.defineProperty(obj, prop, descriptor)
const object1 = {};
Object.defineProperty(object1, 'property1', {
value: 42,
writable: false
});
object1.property1 = 77;//严格模式下会报错
console.log(object1.property1);
// 42
proxy
为一个对象设置代理,这个代理为这个对象的方法设置拦截并进行处理。
兼容:
IE不支持
基础用法:
有两个参数,target 目标对象,handler 处理方法。
const proxy1 = new Proxy(target, handler);
重置目标对象的 get 方法
const target = {
message1: "hello",
message2: "everyone"
};
const handler3 = {
get: function (target, prop, receiver) {
if (prop === "message2") {
return "world";
}
return Reflect.get(...arguments);
},
};
const proxy3 = new Proxy(target, handler3);
console.log(proxy3.message1); // hello
console.log(proxy3.message2); // world
在 JavaScript 对象中可以完全复制所有属性,但对浏览器dom对象不起作用。
const target = {};
const p = new Proxy(target, {});
p.a = 37;
console.log(target.a);
// 37
// 目标对象被修改了
可以在 proxy 中进行验证
let validator = {
set: function(obj, prop, value) {
if (prop === 'age') {
if (!Number.isInteger(value)) {
throw new TypeError('The age is not an integer');
}
if (value > 200) {
throw new RangeError('The age seems invalid');
}
}
// 设置value值
obj[prop] = value;
// 返回成功
return true;
}
};
const person = new Proxy({}, validator);
person.age = 100;
console.log(person.age); // 100
person.age = 'young'; // Throws an exception
person.age = 300; // Throws an exception
DOM操作
let view = new Proxy(
{
selected: null // target
},
{// handler
set: function(obj, prop, newval) {
let oldval = obj[prop];
if (prop === 'selected') {
if (oldval) {
oldval.setAttribute('aria-selected', 'false');
}
if (newval) {
newval.setAttribute('aria-selected', 'true');
}
}
// 修改属性值
obj[prop] = newval;
// 返回成功
return true;
}
});
let i1 = view.selected = document.getElementById('item-1'); //i1 是 null
console.log(i1.getAttribute('aria-selected'));
// 'true'
let i2 = view.selected = document.getElementById('item-2');
console.log(i1.getAttribute('aria-selected'));
// 'false'
console.log(i2.getAttribute('aria-selected'));
// 'true'
Note: even if selected: !null, then giving oldval.setAttribute is not a function
Reflect
Reflect 是内置的,不可修改,提供了拦截javascript操作的方法。Reflect的所有属性和方法都是静态的。其中的一些方法与 Object 的方法相同。
和 Proxy 配合使用,例如访问对象的 set、deleteProperty 等方法,返回true/false;get 方法,返回属性的值。
WeakMap
WeakMap 对象是一组键/值对的集合,其中的键是弱引用的。其键必须是对象,而值可以是任意的。
Object.create()
创建一个新对象。
浏览器支持:
IE9
用法:
Object.create(proto, [propertiesObject])
const person = {
isHuman: false,
printIntroduction: function() {
console.log(My name is ${this.name}. Am I human? ${this.isHuman});
}
};
const me = Object.create(person);
me.name = 'Matthew'; // 修改了"me"的"name",没有修改 "person"的
me.isHuman = true; // 继承属性可以被重写
me.printIntroduction();
// "My name is Matthew. Am I human? true"
Object.getOwnPropertyDescriptor()
返回一个对象,描述目标对象的一个属性。
兼容性:
IE9+,IE8中只能用在DOM对象上。
用法:
Object.getOwnPropertyDescriptor(obj, prop)
const object1 = {
property1: 42
};
const descriptor1 = Object.getOwnPropertyDescriptor(object1, 'property1');
console.log(descriptor1.configurable);
// true
console.log(descriptor1.value);
// 42
相关链接:
参考:
