Mid-level 7 min · March 06, 2026

JavaScript Object Methods — Arrow Functions Break 'this'

A production outage caused 'Name: undefined' due to arrow function methods.

N
Naren Founder & Principal Engineer

20+ years shipping production JavaScript and front-end systems at scale. Written from production experience, not tutorials.

Follow
Production
production tested
May 23, 2026
last updated
1,554
articles · all by Naren
 ● Production Incident 🔎 Debug Guide ⚙ Triage Commands
Quick Answer
  • Object methods are functions stored as object properties — they let data act on itself
  • Use shorthand syntax: methodName() {} instead of methodName: function() {}
  • 'this' inside a method refers to the object that owns the method — but only with regular functions
  • Arrow functions don't bind their own 'this' — they break method behavior
  • Built-in Object.keys(), Object.values(), Object.entries() inspect any object
  • Methods show up in Object.keys() — use typeof filter to exclude them from loops
✦ Definition~90s read
What is Object Methods in JavaScript?

A method is just a function — but instead of floating freely in your code, it's attached to an object as one of its properties. That's it. If you already know what a function is, you already know 90% of what a method is.

Think of a JavaScript object like a person on a contact card.

Here's the mental model: an object has two kinds of properties. Data properties store values — strings, numbers, booleans. Method properties store functions. When a function is stored inside an object, we call it a method.

Why does this matter? Because that method can then use 'this' to refer to the object it's sitting inside. It can read the object's own data, update it, or compute something from it — all without needing anything passed in from outside. The method and the data are teammates living in the same house.

You write a method exactly like you write a normal property, except instead of assigning a string or number as the value, you assign a function. You can use the traditional 'function' keyword or the modern shorthand syntax — both work, and you'll see both in real codebases.

Plain-English First

Think of a JavaScript object like a person on a contact card. The card stores data — name, age, phone number. But a real person can also DO things — wave, introduce themselves, calculate their own age from their birthday. Object methods are the 'doing' part. They're functions that live inside an object, giving your data the ability to act on itself. Instead of just storing 'name: Sarah', your object can have a method called 'greet' that says 'Hi, I'm Sarah!' all by itself.

Every app you've ever used is built on data that does things. A user profile doesn't just store a name — it can update itself, calculate a display label, or check whether the account is verified. A shopping cart doesn't just hold items — it can total the price, apply a discount, or check if it's empty. That 'doing' capability is powered by object methods, and it's one of the most important patterns in JavaScript.

Without object methods, you'd write separate functions scattered all over your code — one to greet a user, another to format their name, another to check their status. That gets messy fast. Methods solve this by packaging the behavior directly alongside the data it operates on. The logic lives where it belongs: inside the object itself.

By the end of this article, you'll know exactly how to write methods inside objects, how to use the 'this' keyword to let a method access its own object's data, how to call methods correctly, and how to use JavaScript's powerful built-in object methods like Object.keys(), Object.values(), and Object.entries(). You'll go from 'I sort of get objects' to 'I can actually build something with this.'

What Is an Object Method? Functions That Belong to an Object

A method is just a function — but instead of floating freely in your code, it's attached to an object as one of its properties. That's it. If you already know what a function is, you already know 90% of what a method is.

Here's the mental model: an object has two kinds of properties. Data properties store values — strings, numbers, booleans. Method properties store functions. When a function is stored inside an object, we call it a method.

Why does this matter? Because that method can then use 'this' to refer to the object it's sitting inside. It can read the object's own data, update it, or compute something from it — all without needing anything passed in from outside. The method and the data are teammates living in the same house.

You write a method exactly like you write a normal property, except instead of assigning a string or number as the value, you assign a function. You can use the traditional 'function' keyword or the modern shorthand syntax — both work, and you'll see both in real codebases.

BasicObjectMethod.jsJAVASCRIPT
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
// A plain object representing a user profile
const userProfile = {
  firstName: 'Sarah',
  lastName: 'Chen',
  age: 28,

  // This is a METHOD — a function stored as a property
  // 'this' refers to the userProfile object itself
  getFullName: function () {
    return this.firstName + ' ' + this.lastName;
  },

  // Modern shorthand syntax — does exactly the same thing
  // No 'function' keyword needed — cleaner and preferred in modern JS
  greet() {
    return 'Hi! My name is ' + this.getFullName() + ' and I am ' + this.age + ' years old.';
  },

  // A method that UPDATES the object's own data
  celebrateBirthday() {
    this.age = this.age + 1; // increment age on the object itself
    return 'Happy birthday, ' + this.firstName + '! You are now ' + this.age + '.';
  }
};

// Calling a method: objectName.methodName()
console.log(userProfile.getFullName());     // call getFullName method
console.log(userProfile.greet());           // call greet method
console.log(userProfile.celebrateBirthday()); // call celebrateBirthday — also changes age
console.log('Updated age:', userProfile.age); // confirm the age was actually updated
Output
Sarah Chen
Hi! My name is Sarah Chen and I am 28 years old.
Happy birthday, Sarah! You are now 29.
Updated age: 29
Pro Tip: Shorthand Is the Modern Standard
The shorthand method syntax (writing 'greet() {}' instead of 'greet: function() {}') is preferred in modern JavaScript. It's less to type, easier to read, and is what you'll see in professional codebases. Use it by default unless you have a specific reason not to.
Production Insight
Methods that update object state (like celebrateBirthday) mutate the original object.
If you accidentally reassign the object variable elsewhere, you lose the reference — the method updates a different object.
Rule: treat method mutation as intentional; prefer immutable returns unless performance demands otherwise.
Key Takeaway
A method is a function tied to an object.
It uses 'this' to read and write its own object's data.
Shorthand syntax is the modern standard — use it.
JavaScript Object Methods & 'this' Binding THECODEFORGE.IO JavaScript Object Methods & 'this' Binding How arrow functions break 'this' and how to fix it Object Method Definition Function as property value of an object Regular Function 'this' 'this' refers to the calling object Arrow Function 'this' 'this' is lexically inherited, not dynamic Method Shorthand (ES6) Omits colon and function keyword Method Chaining Return 'this' for fluent API calls ⚠ Arrow functions in methods lose dynamic 'this' Use regular functions or method shorthand for object methods THECODEFORGE.IO
thecodeforge.io
JavaScript Object Methods & 'this' Binding
Object Methods Javascript

The 'this' Keyword Inside Methods — How a Method Knows Its Own Data

'this' is the word that makes methods genuinely useful. It's a special keyword that, inside a method, points to the object the method belongs to. It's how a method says 'I want to use MY object's data, not some variable from somewhere else.'

Imagine you're an employee at a company. When you say 'my manager', you don't need to explain who you are — 'my' automatically refers to you and your specific context. 'this' works the same way inside a method. When a method says 'this.name', it means 'the name property of the object I belong to.'

This is why methods are more powerful than regular functions for object-related work. A standalone function would need the object passed in as a parameter every single time. A method already knows which object it belongs to, so it can access that data directly.

The key rule to remember for now: inside a method written with 'function' keyword or shorthand syntax inside an object literal, 'this' is the object to the left of the dot when you call the method. 'userProfile.greet()' — 'this' is 'userProfile'. Clear, predictable, useful.

ThisKeywordInMethods.jsJAVASCRIPT
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
// A bank account object — notice how every method uses 'this'
// to access and modify the account's OWN data
const bankAccount = {
  ownerName: 'Marcus Johnson',
  balance: 1000,
  currency: 'USD',

  // 'this.balance' reads the balance from THIS specific object
  getBalance() {
    return this.ownerName + "'s balance: " + this.currency + ' ' + this.balance;
  },

  // 'this.balance' is updated — changes the object's own property
  deposit(amount) {
    if (amount <= 0) {
      return 'Deposit amount must be greater than zero.';
    }
    this.balance = this.balance + amount; // update THIS object's balance
    return 'Deposited ' + amount + '. New balance: ' + this.balance;
  },

  withdraw(amount) {
    if (amount > this.balance) {
      // 'this.balance' checks THIS account's funds — not some global variable
      return 'Insufficient funds. Current balance: ' + this.balance;
    }
    this.balance = this.balance - amount;
    return 'Withdrew ' + amount + '. Remaining balance: ' + this.balance;
  },

  // A method calling OTHER methods on the same object using 'this'
  printStatement() {
    return [
      '--- Account Statement ---',
      'Owner: ' + this.ownerName,
      this.getBalance()  // calling another method via 'this' is valid!
    ].join('\n');
  }
};

console.log(bankAccount.getBalance());
console.log(bankAccount.deposit(500));
console.log(bankAccount.withdraw(200));
console.log(bankAccount.withdraw(5000)); // try to overdraw
console.log(bankAccount.printStatement());
Output
Marcus Johnson's balance: USD 1000
Deposited 500. New balance: 1500
Wwithdrew 200. Remaining balance: 1300
Insufficient funds. Current balance: 1300
--- Account Statement ---
Owner: Marcus Johnson
Marcus Johnson's balance: USD 1300
Watch Out: Arrow Functions Break 'this' in Methods
Never use an arrow function (=>) to define an object method if you need 'this'. Arrow functions don't get their own 'this' — they inherit it from the surrounding scope, which is usually the global window object, not your object. Use regular function syntax or shorthand. Arrow functions are great inside methods (like inside a .forEach()), but not AS the method itself.
Production Insight
When you destructure a method from an object (e.g., const { deposit } = bankAccount), 'this' is lost.
Calling deposit(100) then throws 'Cannot read properties of undefined'.
Fix: call the method as bankAccount.deposit(100) or use .bind(bankAccount).
Key Takeaway
'this' inside a method = the object left of the dot at call time.
Arrow functions inherit 'this' from the enclosing scope — never use them as methods.
If you extract a method, its 'this' breaks — keep it attached.

Built-In JavaScript Object Methods — Object.keys(), Object.values(), and Object.entries()

JavaScript ships with several powerful built-in methods that sit on the global 'Object' constructor (capital O). These aren't methods you call on your object — you pass your object into them. They're utility tools for inspecting and working with any object.

Think of them like tools in a toolbox. Your object is a box of stuff. Object.keys() gives you a list of all the labels on the box. Object.values() gives you a list of all the actual contents. Object.entries() gives you both — each label paired with its contents — which is perfect for looping.

Object.keys() returns an array of all the property names (keys) of an object. Object.values() returns an array of all the property values. Object.entries() returns an array of [key, value] pairs. All three ignore inherited properties and only return the object's own directly-defined properties.

These three are genuinely used every day in professional JavaScript. Object.entries() combined with a loop or .map() is one of the most common patterns for transforming data, building UI components, and debugging. Learning them now will pay off immediately.

BuiltInObjectMethods.jsJAVASCRIPT
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
// A product in an online store
const laptopProduct = {
  name: 'ProBook 15',
  brand: 'TechCore',
  price: 1299,
  inStock: true,
  rating: 4.7
};

// Object.keys() — get all the property NAMES as an array
const propertyNames = Object.keys(laptopProduct);
console.log('Property names:', propertyNames);

// Object.values() — get all the property VALUES as an array
const propertyValues = Object.values(laptopProduct);
console.log('Property values:', propertyValues);

// Object.entries() — get [key, value] pairs — great for looping
const propertyPairs = Object.entries(laptopProduct);
console.log('Key-value pairs:', propertyPairs);

// Real-world use: loop over entries to display each field
console.log('\n--- Product Details ---');
Object.entries(laptopProduct).forEach(function ([key, value]) {
  // Destructure each [key, value] pair directly in the parameter
  console.log(key + ': ' + value);
});

// Object.assign() — copy properties from one object into another
// Useful for merging objects or creating shallow copies
const discountedProduct = Object.assign({}, laptopProduct, { price: 999, onSale: true });
// {} is the target (new empty object), laptopProduct is copied in, then overrides are applied
console.log('\nOriginal price:', laptopProduct.price);    // original unchanged
console.log('Discounted price:', discountedProduct.price); // new object has new price
console.log('On sale flag:', discountedProduct.onSale);    // new property added

// Object.freeze() — lock an object so nothing can change it
const appConfig = Object.freeze({
  apiUrl: 'https://api.example.com',
  version: '2.1.0',
  maxRetries: 3
});

appConfig.version = '9.9.9'; // silently fails in non-strict mode
console.log('\nConfig version (unchanged):', appConfig.version); // still 2.1.0
Output
Property names: [ 'name', 'brand', 'price', 'inStock', 'rating' ]
Property values: [ 'ProBook 15', 'TechCore', 1299, true, 4.7 ]
Key-value pairs: [ [ 'name', 'ProBook 15' ], [ 'brand', 'TechCore' ], [ 'price', 1299 ], [ 'inStock', true ], [ 'rating', 4.7 ] ]
--- Product Details ---
name: ProBook 15
brand: TechCore
price: 1299
inStock: true
rating: 4.7
Original price: 1299
Discounted price: 999
On sale flag: true
Config version (unchanged): 2.1.0
Interview Gold: Object.keys().length vs hasOwnProperty
A classic interview question asks how to check if an object is empty. The cleanest answer: Object.keys(myObject).length === 0. This returns true only if the object has no own enumerable properties. Avoid checking 'for...in' alone — it also picks up inherited properties, which is rarely what you want.
Production Insight
Object.assign() only does shallow copy — nested objects are shared by reference.
If your config object has nested objects, assigning a new value to a nested property also mutates the original.
Use structuredClone() for deep cloning in production; JSON.parse(JSON.stringify()) is a common fallback but drops functions and undefined.
Key Takeaway
Object.keys(), .values(), .entries() are daily tools for inspecting objects.
.entries() is the most flexible — key and value together.
Remember: methods are properties — they show up unless you filter them out.

Adding Methods to Existing Objects and Checking What an Object Can Do

You're not locked in to only the methods you define when you first create an object. JavaScript lets you add new methods to an existing object at any time — you just assign a function to a new property name. This is incredibly flexible and comes up constantly when you're building dynamic applications.

You might start with a plain data object from an API — just properties, no methods. Then in your application code, you can bolt on methods to give it behavior. It's like receiving a plain contact card and then writing your own notes and shortcuts on it.

You can also check whether a method (or any property) exists on an object before trying to call it using 'typeof' or the 'in' operator. This prevents runtime errors in situations where you're not sure what shape an object will have — which happens all the time when working with data from external APIs.

And if you ever need to remove a method or property from an object, the 'delete' operator does exactly that. It permanently removes the property from the object.

AddingAndCheckingMethods.jsJAVASCRIPT
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
// Start with a plain data object — no methods, just properties
const movieRecord = {
  title: 'The Lost Horizon',
  director: 'Elena Vasquez',
  releaseYear: 2019,
  ratingOutOf10: 8.4,
  genre: 'Sci-Fi'
};

// Add a method to the existing object AFTER creation
// Just assign a function to a new property name
moviewRecord.getSummary = function () {
  return this.title + ' (' + this.releaseYear + ') — directed by ' + this.director;
};

// Oops — typo above. Let's do it correctly:
movieRecord.getSummary = function () {
  return this.title + ' (' + this.releaseYear + ') — directed by ' + this.director;
};

movieRecord.isHighlyRated = function () {
  // Returns true if rating is 8.0 or above
  return this.ratingOutOf10 >= 8.0;
};

movieRecord.getAgeOfFilm = function () {
  const currentYear = new Date().getFullYear(); // get the current year dynamically
  return currentYear - this.releaseYear + ' years old';
};

console.log(movieRecord.getSummary());
console.log('Highly rated?', movieRecord.isHighlyRated());
console.log('Film age:', movieRecord.getAgeOfFilm());

// Check if a method exists before calling it — safe practice
if (typeof movieRecord.getSummary === 'function') {
  console.log('getSummary method exists — safe to call');
}

// The 'in' operator checks for ANY property (including non-functions)
console.log('Has director property?', 'director' in movieRecord); // true
console.log('Has budget property?', 'budget' in movieRecord);     // false

// Delete a property (or method) from an object
console.log('\nBefore delete — genre:', movieRecord.genre); // Sci-Fi
delete movieRecord.genre;
console.log('After delete — genre:', movieRecord.genre);  // undefined

// See all current keys to confirm what's on the object
console.log('\nAll current keys:', Object.keys(movieRecord));
Output
The Lost Horizon (2019) — directed by Elena Vasquez
Highly rated? true
Film age: 6 years old
getSummary method exists — safe to call
Has director property? true
Has budget property? false
Before delete — genre: Sci-Fi
After delete — genre: undefined
All current keys: [ 'title', 'director', 'releaseYear', 'ratingOutOf10', 'getSummary', 'isHighlyRated', 'getAgeOfFilm' ]
Pro Tip: Methods Show Up in Object.keys()
When you add methods directly on an object literal or via assignment, they appear in Object.keys() just like data properties do. If you want to loop only over data properties (not functions), filter with: Object.keys(obj).filter(key => typeof obj[key] !== 'function'). This is a common real-world pattern when serializing objects.
Production Insight
Adding methods after object creation means they are own enumerable properties — they appear in for...in and Object.keys().
If you later iterate with for...in and call each value as a function on the wrong type, you get runtime errors.
Solution: always check typeof before calling, or separate data and behavior into different objects.
Key Takeaway
You can add methods any time — just assign a function to a new property.
Use typeof or the 'in' operator to check existence before calling.
Delete removes properties permanently — use with caution.

Method Chaining: Return 'this' to Build Fluent APIs

You've seen it in jQuery, Lodash, and even JavaScript's array methods: chaining calls like arr.filter().map().reduce(). You can build the same pattern in your own objects. The trick: each method returns the object itself ('this'), so the next method can be called directly on the result.

Method chaining reduces noise. Instead of nesting functions or storing intermediate results in multiple variables, you chain calls. The code reads left-to-right, like a sentence: 'object.firstMethod().secondMethod().thirdMethod()'.

To enable chaining, every method that's intended to be chained must 'return this;' at the end. Methods that return a value (like a getter) break the chain — you can't call another method on a string or number. Chaining works best with setter-like methods that modify the object and then hand it back.

MethodChaining.jsJAVASCRIPT
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
// A calculator object with chainable methods
const calculator = {
  value: 0,

  add(n) {
    this.value += n;
    return this; // enable chaining
  },

  subtract(n) {
    this.value -= n;
    return this;
  },

  multiply(n) {
    this.value *= n;
    return this;
  },

  getResult() {
    return this.value; // breaks the chain — returns a number
  }
};

// Chained calls — clean and readable
const result = calculator
  .add(10)
  .subtract(2)
  .multiply(3)
  .getResult();

console.log('Result:', result); // (10 - 2) * 3 = 24

// Without chaining — intermediate variables everywhere
const calc2 = { value: 0 };
calc2.value += 10;
calc2.value -= 2;
calc2.value *= 3;
console.log('Manual result:', calc2.value);

// Real-world: form builder using chaining
const formBuilder = {
  fields: [],
  addField(type, label) {
    this.fields.push({ type, label });
    return this;
  },
  build() {
    return this.fields;
  }
};

const myForm = formBuilder
  .addField('text', 'Name')
  .addField('email', 'Email')
  .addField('submit', 'Send')
  .build();

console.log('Form fields:', myForm);
Output
Result: 24
Manual result: 24
Form fields: [
{ type: 'text', label: 'Name' },
{ type: 'email', label: 'Email' },
{ type: 'submit', label: 'Send' }
]
Mental Model: The Builder Pattern
  • Return 'this' from every setter-like method to enable chaining.
  • Terminal methods (like build() or getResult()) return a value and end the chain.
  • Chaining eliminates intermediate variables — code flows top to bottom.
  • Over-chaining can hurt readability if the chain is longer than 5–7 calls.
Production Insight
Chaining with 'return this' works only if the object is mutable.
If you return a new object (for immutability), chaining requires a different pattern (like spread operator in each method).
Rule: decide mutable vs immutable before architecting chaining — mixing the two confuses consumers.
Key Takeaway
Return 'this' from methods to enable fluent chaining.
Terminal methods return a value and break the chain.
Chaining improves readability when each step is a clear transformation.

Object Methods in Practice: Real-World Patterns

You've learned the mechanics. Now let's see where object methods shine in production code. The most common patterns are: factory functions that return objects with methods, methods that coordinate multiple internal calls, and methods that serialize the object for networking.

Factory functions are a clean alternative to classes when you need to create multiple objects with the same behavior. You write a function that returns a new object with methods. Each call creates a fresh object with its own data and the same method definitions. This avoids the confusion of 'this' in classes and is common in React's functional components and in configuration objects.

Another pattern is a method that aggregates data from multiple sources. For example, a 'getSummary' method might concatenate several computed properties instead of requiring the caller to do it. This keeps the formatting logic inside the object, not scattered across the codebase.

Finally, a 'toJSON' method is a JavaScript convention. If an object has a toJSON method, JSON.stringify() will call it automatically. This lets you control exactly how your object is serialized — filter out sensitive fields, rename keys, or flatten structures.

RealWorldObjectPatterns.jsJAVASCRIPT
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
// 1. Factory function — returns a new object with methods
function createUser(firstName, lastName, age) {
  return {
    firstName,
    lastName,
    age,
    getFullName() {
      return `${this.firstName} ${this.lastName}`;
    },
    canDrink() {
      // Age check based on US law — could be configurable
      return this.age >= 21;
    }
  };
}

const user1 = createUser('Alice', 'Smith', 30);
const user2 = createUser('Bob', 'Jones', 17);
console.log(user1.getFullName(), user1.canDrink()); // Alice Smith true
console.log(user2.getFullName(), user2.canDrink()); // Bob Jones false

// 2. Method that aggregates multiple data sources
const order = {
  items: [
    { name: 'Widget', price: 10, qty: 2 },
    { name: 'Gadget', price: 25, qty: 1 }
  ],
  discount: 5, // flat $ discount

  getSubtotal() {
    return this.items.reduce((sum, item) => sum + item.price * item.qty, 0);
  },
  getTotal() {
    return this.getSubtotal() - this.discount;
  },
  getSummary() {
    return `Order: $${this.getTotal()} (${this.items.length} items, discount $${this.discount})`;
  }
};

console.log(order.getSummary());

// 3. toJSON method — custom serialization
const user = {
  name: 'John',
  password: 'secret',
  role: 'admin',
  toJSON() {
    // Serialize only safe fields
    return {
      name: this.name,
      role: this.role
    };
  }
};

console.log(JSON.stringify(user)); // {"name":"John","role":"admin"}
Output
Alice Smith true
Bob Jones false
Order: $65 (2 items, discount $5)
{"name":"John","role":"admin"}
Pro Tip: toJSON Is a Protocol, Not a Requirement
toJSON is not part of any built-in call — it's a contract honored by JSON.stringify(). Any object with toJSON will be serialized using that method. Use it to strip sensitive data (passwords, tokens) before sending objects over the network.
Production Insight
Factory functions create a new object with fresh methods each call — memory overhead is higher than class prototypes.
For objects created inside hot loops (e.g., rendering thousands of list items), consider using a class or Object.create to share method definitions.
Rule: use factories for configuration objects or small numbers of instances; use classes for performance-sensitive collections.
Key Takeaway
Factory functions return objects with methods — clean and clear.
toJSON controls serialization — strip secrets before sending over the wire.
Aggregate methods keep formatting logic inside the object, not in callers.

Object Method Shorthand — ES6 Syntax That Doesn't Waste Cycles

Before ES6, you wrote methods like prisoners chained to a syntax rock: greet: function() { ... }. The colon, the function keyword — it's noise. The machine doesn't care, but your eyes do when scanning a 400-line service object.

ES6 gave us method definitions. No colon. No function. Just the name and parentheses. It's not sugar — it's clarity. When you see log() { ... } vs log: function() { ... }, the first tells you "this is a method that acts on object state." The second screams "somebody copy-pasted from 2011."

Why does this matter in production? Because every byte of cognitive overhead adds up during incident response. You want your code to communicate intent, not ceremonial syntax. If you're using TypeScript, method shorthand also plays nicer with this typing. Less friction when you need to refactor.

One gotcha: method shorthand still binds this dynamically. If you pass that method as a callback without arrow-function wrapping, you'll lose your reference. Know your this rules before you abbreviate.

ConfigStore.jsJAVASCRIPT
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
// io.thecodeforge — javascript tutorial

const configStore = {
  cache: new Map(),
  
  // Old syntax — verbose, distracting
  loadConfig: function(key) {
    return this.cache.get(key) ?? 'DEFAULT';
  },
  
  // Method shorthand — clean, intentional
  setConfig(key, value) {
    this.cache.set(key, value);
    return this;
  },
  
  clear(key) {
    this.cache.delete(key);
    return this;
  }
};

configStore.setConfig('db_host', 'prod-01.example.com');
console.log(configStore.loadConfig('db_host'));
Output
prod-01.example.com
Senior Shortcut:
Method shorthand does NOT bind this to the object. Passing configStore.loadConfig as a DOM event handler? You'll get undefined unless you wrap it in an arrow function or use .bind(this).
Key Takeaway
Use ES6 method shorthand for all object methods — it's less noise, shorter lines, and signals you know modern JavaScript.

Updating or Adding a Method to an Object — Mutation You Own

Objects in JavaScript are mutable by default. You can add a method anytime — even after the object is created. This isn't a bug, it's a feature of a dynamic language. But with great power comes responsibility: if you're adding methods to an object that's passed through six different modules, you're now debugging a ghost.

Here's the pattern: obj.newMethod = function() { ... } or obj['newMethod'] = function() { ... }. Works on any object, including instances of classes. But ask yourself: am I augmenting a well-known object (like adding a utility to a config object I control) or am I monkey-patching something that belongs to a library?

If it's the latter, stop. Really. Monkey-patching breaks when the library updates. You'll be the one debugging a Node.js upgrade at 3 AM because your Array.prototype.clear() overload is now colliding with a native method.

Instead, use Object.defineProperty() if you need to control whether the method is enumerable, writable, or configurable. That's the production-grade approach — especially when working with APIs or data that maps from JSON and needs behaviour attached after parse.

UserSession.jsJAVASCRIPT
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
// io.thecodeforge — javascript tutorial

const session = {
  id: 'sess_abc123',
  userId: 'usr_42',
  expiresAt: Date.now() + 3600000
};

// Add method after creation — used in middleware
session.refresh = function() {
  this.expiresAt = Date.now() + 3600000;
  return this;
};

// Production: control property descriptor
Object.defineProperty(session, 'isValid', {
  value: function() {
    return Date.now() < this.expiresAt;
  },
  writable: false,
  enumerable: false,
  configurable: false
});

session.refresh();
console.log(session.isValid());
Output
true
Production Trap:
Adding methods directly to Object.prototype pollutes every object — including {} literals. Always check if you're mutating a prototype chain you don't own. If yes, use Object.defineProperty with enumerable: false to keep it invisible during for...in loops.
Key Takeaway
Add methods after creation when it makes sense — but use Object.defineProperty for production code to control visibility and protect against accidental override.
● Production incidentPOST-MORTEMseverity: high

Production Outage Caused by Arrow Function Methods

Symptom
User profile dashboard showed 'Name: undefined', 'Age: undefined' for all users. No error in console initially — data simply vanished.
Assumption
The developer assumed arrow functions were just shorter syntax and used them everywhere, including object methods. Code passed code review because it looked clean.
Root cause
The object method was defined as an arrow function: getUserData: () => { return this.name; }. Arrow functions don't have their own 'this' — they inherit from the surrounding scope, which in this case was the global window object (or undefined in strict mode). 'this.name' never pointed to the object's data.
Fix
Replaced all object method arrow functions with shorthand syntax: getUserData() { return this.name; }. Also added a lint rule to flag arrow functions as object properties.
Key lesson
  • Never use arrow functions to define object methods when they need access to 'this'.
  • Enforce this rule with ESLint's 'no-arrow-functions-in-object-properties' custom rule or similar.
  • Code review check: if you see an arrow function assigned to a property of an object literal or class, question it.
Production debug guideSymptom → Action guide for the most common method-related failures4 entries
Symptom · 01
'this' is undefined or refers to window inside a method
Fix
Check the method definition: replace arrow function with shorthand syntax. Verify the method is called as object.method(). If the method is extracted (e.g., const fn = obj.method), 'this' will be lost — use bind or call.
Symptom · 02
Calling a method without parentheses returns function code instead of executing
Fix
Add parentheses: obj.method() not obj.method. The parentheses trigger the function execution.
Symptom · 03
Object.keys() includes methods when you only wanted data properties
Fix
Filter with Object.keys(obj).filter(key => typeof obj[key] !== 'function'). Methods are technically properties — they show up.
Symptom · 04
Data from a method is undefined but the method seems correct
Fix
Check if the method is using 'this' correctly. Log 'this' inside the method. If it's the wrong object, the method might have been detached from its owner.
★ Quick Debug Cheat Sheet for Object MethodsCommands and checks to resolve method issues fast — no theory, just action.
this is wrong/undefined
Immediate action
Check method syntax: must not be arrow function. Use shorthand or function keyword.
Commands
console.log(this) inside method to see what 'this' actually is
obj.constructor.prototype to verify the method is on the prototype if using classes
Fix now
Replace arrow definition: myMethod() {} instead of myMethod: () => {}
Method not running when called+
Immediate action
Check for missing parentheses: obj.method not obj.method(). Check for misspelled method name.
Commands
console.log(typeof obj.method) — should be 'function'
console.log(Object.keys(obj)) to see if method is present
Fix now
Add parentheses or correct spelling
Data property shows method source code+
Immediate action
You're calling it without parentheses somewhere in template or string interpolation.
Commands
Search for the property name without () in your codebase
Use console.log(obj.method()) to confirm correct output
Fix now
Add () where the method is referenced
Object Methods vs Built-In Object Methods
AspectObject Method (Custom)Built-In Object Method
Where it livesInside your object as a propertyOn the global Object constructor
How you call itmyObject.methodName()Object.keys(myObject)
Uses 'this'?Yes — 'this' is the object it belongs toNo — takes the object as an argument
PurposeGive specific objects their own behaviorUtility operations that work on any object
Can you modify it?Yes — reassign or delete at any timeNo — these are built-in and read-only
Common examplesgreet(), calculateTotal(), isActive()Object.keys(), Object.values(), Object.freeze()
When to useWhen the logic belongs to that specific objectWhen you need to inspect, copy or lock objects

Key takeaways

1
A method is just a function stored as a property on an object
it gives your data the ability to act on itself, not just store values.
2
'this' inside a method refers to the object the method belongs to
it's how a method reads and updates its own object's data without needing anything passed in from outside.
3
Never define object methods with arrow functions if you need 'this'
arrow functions don't bind their own 'this', which silently breaks everything in ways that are hard to debug.
4
Object.keys(), Object.values(), and Object.entries() are your three daily tools for inspecting objects
entries() is especially powerful because you get both the key and value together, perfect for looping and transforming data.
5
Return 'this' from methods to enable fluent chaining
it turns sequential calls into a clean pipeline.

Common mistakes to avoid

3 patterns
×

Using an arrow function as an object method that needs 'this'

Symptom
'this' is undefined or refers to the global window object instead of your object, giving you 'Cannot read properties of undefined' or wrong values
Fix
Always use the shorthand method syntax (greet() {}) or the traditional function keyword (greet: function() {}) for object methods. Only use arrow functions inside methods (e.g. inside a .forEach()), never as the method definition itself.
×

Calling a method without parentheses

Symptom
Instead of getting the method's return value, you see the function's source code printed out (e.g. 'function() { return this.name }')
Fix
Always add () when calling a method. 'userProfile.greet' references the function. 'userProfile.greet()' actually executes it. If you're passing the method to another function, that's a different pattern — but for direct calls, always use parentheses.
×

Assuming Object.assign() creates a deep copy

Symptom
Changing a nested object inside the copy also changes the original, causing mysterious bugs with shared state
Fix
Object.assign() only does a shallow copy. Nested objects are still shared by reference. For a true deep copy, use structuredClone(originalObject) (modern JS) or JSON.parse(JSON.stringify(originalObject)) for simple data objects without functions.
INTERVIEW PREP · PRACTICE MODE

Interview Questions on This Topic

Q01JUNIOR
What is the difference between a function and a method in JavaScript? Ca...
Q02SENIOR
What does 'this' refer to inside an object method, and what happens to '...
Q03SENIOR
If I do 'const copy = Object.assign({}, originalObject)', is 'copy' a co...
Q01 of 03JUNIOR

What is the difference between a function and a method in JavaScript? Can you show me an example of each?

ANSWER
A function is a standalone block of reusable code: function greet() { return 'Hi'; }. A method is a function that is attached to an object as a property. The key difference is that a method has automatic access to the object it belongs to via 'this'. Example: const obj = { name: 'Alice', sayHi() { return 'Hi, ' + this.name; } }; obj.sayHi() is a method.
FAQ · 5 QUESTIONS

Frequently Asked Questions

01
What is the difference between a method and a function in JavaScript?
02
Why does 'this' return undefined inside my object method?
03
How do I loop through all the methods and properties of a JavaScript object?
04
Can I add a method to an object after it's been created?
05
How do I chain methods like jQuery does?
N
Naren Founder & Principal Engineer

20+ years shipping production JavaScript and front-end systems at scale. Written from production experience, not tutorials.

Follow
Verified
production tested
May 23, 2026
last updated
1,554
articles · all by Naren
🔥

That's JS Basics. Mark it forged?

7 min read · try the examples if you haven't

Previous
Array Methods in JavaScript
15 / 16 · JS Basics
Next
JSON Syntax Explained: Objects, Arrays, and Common Mistakes