Reflect, Proxy, Weak*
Reflect API
Отдельный модуль, содержащий различные методы, которые раньше были в Object, но их решили вынести в отдельный модуль. Плюс добавили пару новых плюшек
Зачем?
- Модульность
- Многие вещи пересекаются с Proxy, который является частью Reflect API
Методы из Object
- getOwnPropertyDescriptor(target, name)
- defineProperty(target, name, desc)
- getOwnPropertyNames(target)
- getPrototypeOf(target)
- deleteProperty(target,name)
- freeze(target)
- seal(target)
- preventExtensions(target)
- isFrozen(target)
- isSealed(target)
- isExtensible(target)
- has(target,name)
- hasOwn(target,name)
- keys(target)
Несколько относительно новых вещей
- get(target,name,receiver) - аналог target[name]
- set(target,name,value,receiver) - аналог target[name] = value
- apply(target,thisArg,args) - аналог Function.prototype.apply.call(fun,thisArg,args)
- construct(target,args) - аналог new target(...args)
Proxy
Возможность переопределить поведение существующих объектов
Простой пример
var p = new Proxy(target, handler);handler
- getOwnPropertyDescriptor
- ownKeys
- defineProperty
- deleteProperty
- preventExtensions
- has
- get
- set
- apply
- construct
Пример кода
var handler = {
get: function(target, name){
return name in target?
target[name] :
37;
}
};
var p = new Proxy({}, handler);
p.a = 1;
p.b = undefined;
console.log(p.a, p.b); // 1, undefined
console.log('c' in p, p.c); // false, 37Валидация
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');
}
}
// The default behavior to store the value
obj[prop] = value;
}
};
let person = new Proxy({}, validator);
person.age = 100;
console.log(person.age); // 100
person.age = 'young'; // Throws an exception
person.age = 300; // Throws an exceptionЛогирование
function makeLogger(obj) {
return Proxy.create({
get: function (target, name) {
console.log('get', name, obj);
return obj[name];
},
set: function (target, nave, val) {
console.log('set', name, obj, value);
obj[name] = val;
return true;
}
}, Object.getPrototypeOf(obj));
}WeakMap, WeakSet
Пример кода
var map = new WeakMap(),
element = document.querySelector(".element");
map.set(element, "Original");
// later
var value = map.get(element);
console.log(value); // "Original"
// later still - remove reference
element.parentNode.removeChild(element);
element = null;
value = map.get(element);
console.log(value); // undefinedReflect, Proxy, Weak*
By Pavel Trehubau
Reflect, Proxy, Weak*
- 370