Autobind Decorator is a JavaScript/TypeScript library that provides decorators for automatically binding class methods to their instance context. This eliminates the need for manual .bind(this) calls in event handlers and callbacks, making it particularly useful for React components and other scenarios where methods are passed as references.
npm install autobind-decoratorES6 imports:
import autobind, { boundMethod, boundClass } from "autobind-decorator";Named imports only:
import { boundMethod, boundClass } from "autobind-decorator";CommonJS:
const autobind = require("autobind-decorator");
const { boundMethod, boundClass } = require("autobind-decorator");import { boundMethod } from "autobind-decorator";
class Component {
constructor(value) {
this.value = value;
}
@boundMethod
handleClick() {
console.log(this.value); // 'this' is correctly bound
}
}
const component = new Component(42);
const handler = component.handleClick; // No need for .bind(this)
handler(); // Logs: 42Autobind Decorator is built around three key components:
The boundMethod decorator lazily binds individual methods to their instance context. This is the recommended approach for performance reasons.
/**
* Method decorator that binds a method to its instance context
* @param target - The class prototype where the method is defined
* @param key - The property name/symbol of the method being decorated
* @param descriptor - The original PropertyDescriptor of the method
* @returns PropertyDescriptor with custom getter/setter for lazy binding
* @throws TypeError if applied to non-function properties
*/
function boundMethod(target: object, key: string | symbol, descriptor: PropertyDescriptor): PropertyDescriptor;Usage Example:
class MyClass {
constructor() {
this.data = "Hello World";
}
@boundMethod
getData() {
return this.data;
}
}
const instance = new MyClass();
const extractedMethod = instance.getData;
console.log(extractedMethod()); // "Hello World" - this is bound correctlyThe boundClass decorator applies method binding to all methods on a class prototype. This approach has performance implications and should be avoided in most cases.
/**
* Class decorator that binds all methods on the class prototype
* Automatically discovers methods using Reflect.ownKeys (with fallback to Object.getOwnPropertyNames)
* Supports both string and symbol-keyed methods
* @param target - The class constructor to modify
* @returns The modified class constructor with bound methods
*/
function boundClass(target: new (...args: any[]) => any): new (...args: any[]) => any;Usage Example:
@boundClass
class MyClass {
constructor() {
this.data = "Hello World";
}
getData() {
return this.data;
}
processData() {
return this.data.toUpperCase();
}
}
const instance = new MyClass();
const { getData, processData } = instance;
console.log(getData()); // "Hello World"
console.log(processData()); // "HELLO WORLD"The default export autobind can be used as either a method or class decorator depending on its arguments. This magical behavior is discouraged in favor of explicit usage.
/**
* Polymorphic decorator that can bind methods or classes based on argument count
* When called with 1 argument: functions as class decorator (boundClass)
* When called with 3 arguments: functions as method decorator (boundMethod)
* @param args - Variable arguments determining decorator behavior
* @returns Result of boundClass (1 arg) or boundMethod (3 args)
*/
function autobind(...args: any[]): any;Usage Examples:
// As method decorator
class MyClass {
@autobind
method() {
return this.value;
}
}
// As class decorator
@autobind
class MyClass {
method() {
return this.value;
}
}boundMethod has minimal performance impactboundClass binds all methods upfront, potentially wasting memory for unused methods// boundMethod throws TypeError for non-function properties
class Invalid {
@boundMethod // Throws: TypeError: @boundMethod decorator can only be applied to methods not: undefined
get value() {
return 1;
}
}Error Format: TypeError: @boundMethod decorator can only be applied to methods not: ${typeof property}
Symbol Method Support: Both boundMethod and boundClass fully support symbol-keyed methods:
const methodSymbol = Symbol('myMethod');
class Component {
@boundMethod
[methodSymbol]() {
return this.value;
}
}
// Or with boundClass
@boundClass
class Component {
[methodSymbol]() {
return this.value;
}
}Object.defineProperty behaviorReflect.ownKeys or Symbol support is unavailable// TypeScript definitions
declare const autobind: ClassDecorator & MethodDecorator;
declare const boundMethod: MethodDecorator;
declare const boundClass: ClassDecorator;
// Standard TypeScript decorator types
interface MethodDecorator {
<T>(target: any, propertyKey: string | symbol, descriptor: TypedPropertyDescriptor<T>): TypedPropertyDescriptor<T> | void;
}
interface ClassDecorator {
<TFunction extends Function>(target: TFunction): TFunction | void;
}