Proxy (ES6) cho phép định nghĩa hành vi tùy chỉnh cho các thao tác cơ bản trên object: đọc/ghi property, gọi function, construct, enumerate...
3 thành phần chính
- Target: Object gốc bị "proxy".
- Handler: Object chứa các "trap" (bẫy) — hàm intercept thao tác.
- Traps: Các method như
get,set,has,deleteProperty,apply,construct...
Cú pháp
const proxy = new Proxy(target, handler);
Ví dụ cơ bản: Default value cho property không tồn tại
<script>
const target = { name: 'Ram kumar', age: 27 };
const handler = {
get(target, prop) {
// Nếu property tồn tại → trả về giá trị, ngược lại → default
return prop in target ? target[prop] : 'Content developer';
}
};
const proxy = new Proxy(target, handler);
document.write(proxy.name + '<br>'); // Ram kumar
document.write(proxy.age + '<br>'); // 27
document.write(proxy.designation + '<br>'); // Content developer (default)
document.write(proxy.role + '<br>'); // Content developer (default)
</script>
Các trap thường dùng
| Trap | Intercept thao tác | Tham số |
|---|---|---|
get | proxy.prop | (target, prop, receiver) |
set | proxy.prop = val | (target, prop, value, receiver) |
has | 'prop' in proxy | (target, prop) |
deleteProperty | delete proxy.prop | (target, prop) |
apply | proxy(...args) | (target, thisArg, args) |
construct | new proxy(...args) | (target, args, newTarget) |
ownKeys | Object.keys(proxy), for...in | (target) |
Ví dụ nâng cao: Validation với set trap
const user = {};
const validator = {
set(target, prop, value) {
if (prop === 'age') {
if (!Number.isInteger(value) || value < 0) {
throw new TypeError('Age phải là số nguyên dương');
}
}
if (prop === 'email' && !value.includes('@')) {
throw new TypeError('Email không hợp lệ');
}
target[prop] = value;
return true; // Bắt buộc trả về true (strict mode)
}
};
const proxyUser = new Proxy(user, validator);
proxyUser.age = 25; // OK
proxyUser.age = -5; // TypeError
proxyUser.email = 'a@b.com'; // OK
proxyUser.email = 'invalid'; // TypeError
Lưu ý
- Proxy không thể "unwrap" —
proxy instanceof Targetlà true, nhưngproxy === targetlà false. - Performance: Proxy chậm hơn object thường — chỉ dùng khi cần thiết (validation, logging, reactive system như Vue 3).
- Revokable Proxy:
Proxy.revocable(target, handler)→ trả về{ proxy, revoke }, gọirevoke()để vô hiệu hóa.