Created
December 24, 2020 13:23
-
-
Save wilsoncook/5386f49f99b902169f7746e4dec6e6e9 to your computer and use it in GitHub Desktop.
懒对象:该对象只有在被使用(被访问/设置/删除/遍历属性等)时才会被实例化
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* 构建一个懒对象:该对象只有在被使用(被访问/设置/删除/遍历属性等)时才会被实例化 | |
* 其他方案:采用getter方式,如:module.exports = { get XXX() { return new ClsXXX(); } }; | |
* @param factory 实例化函数 | |
*/ | |
function unstable_makeLazyInstance<T>(factory: () => T): T { | |
let instance: T; | |
function wrap<H extends (...args: any[]) => any>(handle: H): H { | |
return ((...args: any[]) => { | |
if (instance === undefined) instance = factory(); | |
return handle(...args); | |
}) as H; | |
} | |
return new Proxy(Object.create(null), { | |
ownKeys: wrap(target => { | |
return Object.getOwnPropertyNames(instance); | |
}), | |
has: wrap((target, key) => { | |
return key in instance; | |
}), | |
get: wrap((target, key, receiver) => { | |
return (instance as any)[key]; | |
}), | |
set: wrap((target, key, value, receiver) => { | |
(instance as any)[key] = value; | |
return true; | |
}), | |
defineProperty: wrap((target, key, descriptor) => { | |
return Object.defineProperty(instance, key, descriptor); | |
}), | |
deleteProperty: wrap((target, key) => { | |
delete (instance as any)[key]; | |
return true; | |
}), | |
getOwnPropertyDescriptor: (target, key) => { | |
return Object.getOwnPropertyDescriptor(instance, key); | |
}, | |
getPrototypeOf: target => { | |
return Object.getPrototypeOf(instance); | |
}, | |
setPrototypeOf: wrap((target, prototype) => { | |
Object.setPrototypeOf(instance, prototype); | |
return true; | |
}), | |
isExtensible: wrap(target => { | |
return Object.isExtensible(instance); | |
}), | |
preventExtensions: wrap(target => { | |
// 禁止扩展时,proxy和内部对象应该同时被禁止 | |
// 注:preventExtensions返回的是对象 | |
Object.preventExtensions(target); | |
Object.preventExtensions(instance); | |
return true; | |
}), | |
}) as T; | |
} | |
export { unstable_makeLazyInstance as makeLazyInstance }; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment