buildDocs/bindAll.js
import { copyMetadata } from './utils';
/**
* Binds methods of an object to the object itself, overwriting the existing method.
* @export
* @param {string[]} [methods=[]]
* @returns {ClassDecorator}
* @example
*
* @BindAll()
* class MyClass {
* bound() {
* return this;
* }
*
* unbound() {
* return this;
* }
* }
*
* const myClass = new MyClass();
*
* myClass.bound.call(null); // => MyClass {}
* myClass.unbound.call(null); // => MyClass {}
*/
export function BindAll(methods = []) {
return (target) => {
function BindAllWrapper(...args) {
bindAllMethods(target, this, methods);
target.apply(this, args);
}
;
BindAllWrapper.prototype = target.prototype;
return BindAllWrapper;
};
}
function bindAllMethods(target, instance, methods = []) {
let proto = target.prototype;
while (proto && proto !== Object.prototype) {
for (const key of Object.getOwnPropertyNames(proto)) {
const include = methods.length ? methods.indexOf(key) !== -1 : true;
const descriptor = Object.getOwnPropertyDescriptor(proto, key);
if (include && key !== 'constructor' && !instance.hasOwnProperty(key)) {
Object.defineProperty(instance, key, {
value: copyMetadata(instance[key].bind(instance), instance[key]),
configurable: true,
enumerable: descriptor.enumerable,
writable: descriptor.writable
});
}
}
proto = Object.getPrototypeOf(proto);
}
}
export { BindAll as bindAll };
export default BindAll;