JavaScript Function Objects and this
Understand function objects, callable versus constructible functions, call-site this, arrow functions, call/apply/bind, and constructor calls.
Intermediate
A function in JavaScript is more than a reusable piece of source text. Function definitions create function objects. Those objects can be stored, passed around, have properties, be called, and—when they are constructors—be used with
new. The same function syntax can therefore participate in several object-level behaviors.
1. A function is an object you can call
The useful mental model is: a function value is an object with callable behavior. The ECMAScript specification describes a function object in terms of an internal
[[Call]] method. That internal method is what makes the value callable; it is not a JavaScript property you normally read or replace.
Output
Ready to run.
Quick check
Which fact makes
function greet() {}
const result = ;
2. Callable does not mean constructible
JavaScript distinguishes two capabilities. A function object with
[[Call]] is callable. A function object with
[[Construct]] is a constructor and can be used with
new. Every constructor is callable, but not every function object is a constructor. This distinction explains why arrow functions can be called but cannot be used with
new.
Output
Ready to run.
Quick check
Which value can be used with
function Person() {}
const arrow = () => {};
const value = ;
3. The call site determines ordinary-function this
For an ordinary function,
this is not simply “the object where the function was written.” When a property reference is called, the base object supplies the call-time
this value. That is why the same function can observe different objects at different call sites.
Output
Ready to run.
Quick check
In
const box = { value: 7, read() { return this.value; } };
const result = ;
4. Extracting a method changes the call
A method is not permanently glued to its object. If you copy the function into a variable and then call that variable, the property reference is gone. The call no longer supplies the original object as
this. In strict functions this can leave
this as
undefined; in sloppy functions ordinary-call rules can substitute the global object.
Output
Ready to run.
Quick check
What should you expect from this strict-mode call?
"use strict";
function read() { return this.value; }
const fn = read;
const result = ();
5. Strict mode changes what an ordinary call receives
The specification models ordinary functions with a
[[ThisMode]]. A strict function uses the supplied
this value as-is. A non-strict function applies the older global-mode conversion rules when it enters the function. This is one reason strict mode is valuable when teaching or debugging
this.
Output
Ready to run.
Quick check
Which rule is specific to the strict ordinary function?
function read() { "use strict"; return this; }
const result = read.call();
6. Arrow functions capture this lexically
An arrow function does not create its own
this binding. The ECMAScript specification creates it with lexical-this behavior, so a
this reference inside the arrow resolves through an enclosing environment. That makes arrows useful for callbacks that should keep the surrounding function’s
this rather than receive a new one from the callback call site.
Output
Ready to run.
Quick check
What happens to the arrow function’s
const obj = { value: 3, read: () => this };
const result = ;
7. call() and apply() choose the this value for ordinary functions
When you need to invoke an ordinary function with a specific
this, use
call() or
apply(). Both pass a chosen
thisArg. The difference is how the remaining arguments are supplied:
call takes them as individual arguments, while
apply takes an array-like argument list.
Output
Ready to run.
Quick check
Which call supplies the arguments as an array-like list?
function sum(a, b) { return this.base + a + b; }
const result = sum.apply({ base: 10 }, );
8. bind() creates a new function with a fixed this
Use
bind() when you want a new function whose
this is fixed for later calls. Binding can also pre-fill leading arguments. Unlike
call() and
apply(),
bind() does not immediately invoke the target function.
Output
Ready to run.
Quick check
What does
function label() { return this.title; }
const result = label.bind({ title: "JavaScript" });
console.log(result());
const answer = ;
9. new uses constructor behavior
The
new operator invokes a function through its constructor capability. A constructor function can initialize the new object through
this. The created object is then returned unless the constructor explicitly returns another object. This lesson uses only the basic behavior; prototype inheritance is handled in the next object-model lesson.
Output
Ready to run.
Quick check
Inside this constructor, what object does
function User(name) { this.name = name; }
const user = new User("Ada");
const result = user.;
10. Function properties are still object properties
Because functions are objects, they can have properties. Common built-in properties include
name and
length. Ordinary constructor-capable functions also have a
prototype property used by the object model. Treat these as properties of the function object, not as magical extra variables.
Output
Ready to run.
Quick check
Which statement is true?
function add(a, b) {}
add.description = "math";
const result = add.description;
11. Higher-order functions pass function objects around
Once functions are understood as values, higher-order programming becomes straightforward: one function can receive another function, return one, or store one. The
this rules still apply to how the returned or passed function is eventually called.
Output
Ready to run.
Quick check
What does runTwice receive?
function run(task) { return task(); }
function value() { return 7; }
const result = run();
12. Method syntax does not permanently bind this
Object method shorthand makes a function definition concise, but it does not create a permanently bound function. The object used as the call base supplies
this each time an ordinary method is called. If you need a stable callback, explicitly bind it or use an arrow that captures an enclosing
this when that is the intended design.
|
|
The distinction is worth memorizing as a call-site rule:
obj.method() supplies
obj as
this.
13. A practical decision tree for this
When reading code, first identify the function kind. If it is an arrow, look outward for its lexical
this. If it is an ordinary function, inspect how it is called. A property call such as
obj.method() supplies the base object; an ordinary standalone call supplies no property base;
call() and
apply() explicitly supply one;
bind() creates a function that remembers one; and
new enters constructor behavior.
Output
Ready to run.
Quick check
Which expression intentionally fixes this for future calls?
const read = function () { return this.value; };
const fixed = read.({ value: 9 });
14. Runnable practice: build a reusable reporter
Now combine the pieces. The reporter below is an ordinary function that reads
this.prefix. It is used once with
call() and once as a bound function. Then an arrow callback deliberately captures the surrounding method’s
this. Run it and change the context values to see which call controls which function.
Output
Ready to run.
What to remember
Function values are objects with callable behavior; callable and constructible are related but distinct capabilities.
For ordinary functions, inspect the call site to determine
this.Arrow functions capture
thislexically and do not create their own binding.Use
call()andapply()for immediate invocation with an explicitthis; usebind()to create a later-call function with fixedthis.Use
newonly with constructor-capable functions; the prototype/object-model details come next.
Authoring rules
Prefer an ordinary method when its behavior should depend on the object that invokes it.
Prefer an arrow callback when you intentionally want the surrounding
thisto remain unchanged.Do not detach a method and assume it keeps its original receiver; bind it when a stable receiver is required.
Remember that
call()andapply()invoke immediately, whilebind()returns a new function.Do not use
newwith arrow functions or other non-constructors.
Specification references
The governing model is ECMA-262: function objects support
[[Call]], constructors additionally support
[[Construct]], ordinary functions have a
[[ThisMode]], and arrow functions use lexical
this. The specification’s call evaluation also explains why a property reference supplies its base as the call-time
this.
Next step
The next Functions + Object Model lesson will connect these function capabilities to prototypes: own versus inherited properties, prototype chains, descriptors, getters and setters, and object creation through
Object.create().
Ready for practice? Take the JavaScript Function Objects and this quiz or practice the completion exercise.
Thanks for your feedback.
Mark this learning resource complete to track your learning progress.