Proxy对象用于定义基本操作的自定义行为(如属性查找、赋值、枚举、函数调用等)。
由于ES5的限制,ES6新增的Proxy无法被转译成ES5,或者通过Polyfill提供兼容。
ES5中无法实现自定义对象的读取属性、属性赋值等行为,然而对于函数调用与实例化,通过对原函数对象进行代理,是可以实现Polyfill兼容的。
如下,对Proxy支持的拦截操作apply与construct进行兼容处理。
/**
* Proxy部分兼容处理
* 仅支持代理apply与construct
* @author 范围兄 <ambit_tsai@qq.com>
*/
window.Proxy = window.Proxy || function(target, handler){
if(typeof target !== 'function'){
throw new TypeError('Only support function proxy in this polyfill');
}
function __Proxy__(){
if(this instanceof __Proxy__){
// 实例化
var obj;
if(typeof handler.construct === 'function'){
obj = handler.construct(target, arguments);
if(obj && typeof obj==='object'){
return obj;
}else{
throw new TypeError('Proxy handler\'s construct must return an object');
}
}else if(handler.construct == null){
obj = target.apply(this, arguments);
if(obj && typeof obj==='object'){
return obj;
}else{
return this;
}
}else{
throw new TypeError('Proxy handler\'s construct must be a function');
}
}else{
// 函数调用
if(typeof handler.apply === 'function'){
return handler.apply(target, this, arguments);
}else if(handler.apply == null){
return target.apply(this, arguments);
}else{
throw new TypeError('Proxy handler\'s apply must be a function');
}
}
}
Object.setPrototypeOf(__Proxy__, target); // 复制原对象的[[Prototype]]
Object.assign(__Proxy__, target); // 复制原对象的属性
__Proxy__.prototype = target.prototype; // 复制原对象的原型
return __Proxy__;
};