← Debugging Guides

阅读中文版本

JavaScript — TypeError: X is not a function

Diagnose "is not a function" by verifying the value at the call site, checking imports and avoiding this-binding pitfalls.

beginnerdebuggingjavascript

Symptoms

  • TypeError: user.getName is not a function
  • The error appears after changing an import style
  • A callback parameter is undefined when invoked
  • A method loses its receiver when passed as a value

Possible causes

  • The imported binding is not the function expected, for example a namespace versus a default export
  • A property is undefined because of a typo or changed shape
  • A method is detached from its object so this is undefined
  • An array-like is treated as a function or vice versa

Diagnosis steps

Log the type at the call site

console.log(typeof target, target)

Interpretation

The output shows whether the value is undefined, an object or another type, which points to the cause.

Check the import shape

node -e "import('./mod.js').then(m=>console.log(Object.keys(m)))"

Interpretation

A default export versus a named export mismatch means the binding is the module namespace, not the function.

Verify the this binding

const fn = obj.method.bind(obj); fn()

Interpretation

A method called without its receiver has no this, so it may fail or misbehave.

Root cause

The value at the call site is not callable, because it is undefined, the wrong shape from an import, or a detached method, not because the function definition is missing.

Fix

Correct the import style, fix the property name or object shape, and bind methods or call them on their receiver so this is defined.

Verify the fix

Rerun the path and confirm the call succeeds, and confirm the function actually executes by checking its effect or return value.

Symptom walkthrough

A call fails with TypeError: something is not a function. The value being called is either undefined, the wrong kind of object, or a method detached from its receiver. This often follows an import change, such as switching between default and named exports, or passing an object method as a callback without binding it, which loses this.

Fix in practice

Inspect the value at the call site to learn what it actually is, then fix the import shape, the property name or object structure, or bind the method to its receiver. For callbacks, pass a bound function or use an arrow that calls it on the object.

Verification

Rerun the path and confirm the call succeeds, then verify the function ran by checking its side effect or return value. A successful call that also does the right thing confirms the real fix.

Diagnostic commands

Check the behavior with commands like these:

console.log(typeof target, target)
node -e "import('./mod.js').then(m=>console.log(Object.keys(m)))"
const fn = obj.method.bind(obj); fn()