Default Function Properties – Complete Guide to Function's Built-In Variables
Default function properties are the built-in variables available in every function declaration.
In other words, JavaScript, by default, adds the following six (6) properties to your function declarations:
arguments
caller
length
name
prototype
[[Prototype]]
(also known as__proto__
or dunder proto)
Here’s an example:
You can see that the browser returned the play
function containing six (6) properties:
arguments
caller
length
name
prototype
[[Prototype]]
Let’s discuss the six default properties now.
What Is the Default arguments
Property in JavaScript Functions?
JavaScript uses the arguments
property to encase all the arguments (values) you pass to a function’s parameters through the function’s invocator.
Note the following:
- The
arguments
property’s value is an array-like object containing a list of the function’s arguments (parameters’ values). - The
arguments
object also contains default properties such ascallee
andSymbol(Symbol.iterator)
.
Here’s an example:
The snippet above returned the arguments
property’s value (an array-like object containing a list of arguments).
Here’s another example:
The snippet above used some of the arguments
property’s values as part of the returned sentence’s variables.
What Is the Default caller
Property in JavaScript Functions?
caller
references the function that invoked the property’s function.
Here’s an example:
checkPresident()
invoked the checkManager()
function in the snippet above. Therefore, the caller
property referenced checkPresident()
.
The caller
property will return null
for strict, async function, and generator function callers.
Here’s an example:
The caller
property returned null
because checkPresident()
invoked checkManager()
in strict mode.
What Is the Default length
Property in JavaScript Functions?
JavaScript uses the length
property to indicate the function’s total number of regular parameters.
Here’s an example:
The length
property ignores non-regular parameters like the rest parameter. For instance, consider the following code:
The length
property returned 3
because it ignores irregular parameters like the rest parameter (...p4
).
Design and develop at the same time
What Is the Default name
Property in JavaScript Functions?
JavaScript uses the name
property to record the function’s name as defined at its creation.
Here’s an example:
Browsers may use an empty string as an anonymous function’s name.
Here’s an example:
What Is the Default prototype
Property in JavaScript Functions?
The prototype
property stores the features a function will share with its object instances.
In other words, whenever you use the new
operator to construct a new object from an existing function. In that case, JavaScript will share the function’s prototype
property with the newly created object.
JavaScript shares only the features you define in a constructor function’s prototype
property with the constructor’s object instances. It does not share other items, such as the statements in the function’s body.
For instance, the Array()
constructor function has some default properties. However, any new object you create with the new Array()
syntax will inherit only the items in the prototype
property.
Below are eight essential facts to remember about the prototype
property.
1. The return
operator does not cause objects to inherit prototype
Objects that functions produce with the return
keyword do not inherit the prototype
property.
For instance, consider the following code:
In the snippet above,
bestWebsite
’s content is an object thatcompanyProfile()
produced with thereturn
keyword.
Let’s see what will happen if we store a property in the companyProfile()
’s prototype
.
The snippet above returned undefined
because of the following reasons:
- JavaScript could not find a
name
property in thebestWebsite
object. bestWebsite
did not inherit thecompanyProfile
’sprototype
because it is a returned object.
You can make bestWebsite
inherit companyProfile
’s prototype
by creating the object with the new
operator like so:
In the snippet above,
bestWebsite
’s content is an object thatcompanyProfile()
produced with thenew
keyword.
Let’s see what will happen if you store a property in the companyProfile()
’s prototype
.
The snippet above returned "CodeSweetly"
because of the following reasons:
- The
new
keyword caused thebestWebsite
object to inherit thecompanyProfile
’sprototype
property. companyProfile
’sprototype
has aname
property whichbestWebsite
also inherited.
Design in Figma, launch in Webflow
2. An object is prototype
’s default value
The prototype
property’s default value is an object containing constructor
and [[Prototype]]
properties.
For instance, consider the following code:
constructor
references the function itself.[[Prototype]]
references theprototype
property the function inherited from its constructor. We sometimes call it “dunder proto.”
3. The prototype
property is mutable
Although an object is prototype
’s default value, you can change it to any data type or add extra items.
Here’s an example:
You can see that JavaScript gives you complete control of the prototype
property. But “with great freedom comes great responsibility—Eleanor Roosevelt.”
4. Modify prototype
with caution!
Some alterations on the prototype
property will break the inheritance chain of the function and its subsequent object instances. So, be careful while modifying it.
You should prefer adding items to prototype
’s default object rather than replacing it.
For instance, companyProfile.prototype = { name: "value" }
will break companyProfile
’s prototype chain—which you should avoid.
A better alternative is to update the default object by adding items like this: companyProfile.prototype.name = "value"
.
5. New prototype
object needs a new constructor
Suppose you choose to replace prototype
’s default object with a new value. In that case, remember to define a new constructor
property. Otherwise, your function’s prototype
will have no constructor feature. And its object instances will inherit Object()
’s prototype
directly.
Here’s an example:
boxObject2
inherited the global Object
’s prototype
directly because we replaced Box
’s prototype
without providing a new constructor
property.
Create your web presence in no time
6. Avoid modifying built-in objects’ prototype
properties
Extending any built-in prototypes, such as the Object.prototype
, is a bad coding practice because it breaks JavaScript’s prototype chain.
In other words, avoid altering the prototype
property of the objects you did not create.
7. Put static items in the prototype
property
Developers typically structure a constructor function as follows:
- Define dynamic items, like variables, in the constructor function’s body.
- Define static data, like methods, in the constructor function’s
prototype
property.
Here’s an example:
The snippet above structured the constructor function as follows:
MyCar
’s body contains items whose values users may change (dynamic values).MyCar
’sprototype
has items whose value we do not expect users to alter (static value).
Note the following:
- A constructor function contains own and prototype items.
- Own properties are the items in an object’s body.
- Prototype features are the items in an object’s
prototype
property. wheel
,gearbox
, andmirrors
are the owned properties because they are not inheritable through theprototype
property.showFeatures
is a shared feature becauseMyCar
’s object instances will inherit the method through the constructor’sprototype
property.- We used the
this
keyword to assign the own properties toMyCar
’s object instances. - JavaScript creates new own properties whenever you use the
new
keyword to construct a new object instance. In contrast, the computer shares a constructor’s prototype features with all object instances. It doesn’t create new prototype items.
8. Some functions do not have a default prototype
property
Arrow functions, methods, and asynchronous functions do not have built-in prototype
properties. Therefore, you cannot use them as constructor functions—even if you later add a prototype
manually.
For instance, consider the following code:
The invocations in the snippet above returned undefined
because arrow functions, methods, and asynchronous functions do not have built-in prototype
properties.
What Is the Default [[Prototype]]
Property in JavaScript Functions?
[[Prototype]]
is the prototype
property a function (or object) inherits from its constructor.
Here’s an example:
The snippet above returned an object that all the companyProfile
’s object instances will inherit.
In other words, companyProfile.prototype
is equivalent to the companyProfile
’s object instances’ dunder proto.
Here’s an example:
You can see that Object.getPrototypeOf(bestWebsite)
returned the same value as companyProfile.prototype
. The reason is that bestWebsite
’s dunder proto contains the prototype
that the object inherited from its constructor (companyProfile
).
Developers typically use the term “prototype chain” to reference JavaScript’s inheritance system. Let’s see how it works.
Design and develop at the same time
How Does the JavaScript Inheritance System Work?
Consider the constructor function below and its object instance.
The snippet above created mySpecialCar
object from MyCar()
constructor function.
Suppose you invoke a feature that isn’t one of MyCar()
’s own properties (for instance, mySpecialCar.valueOf()
). In that case, here is what JavaScript will do:
1. Check if mySpecialCar
object has a valueOf()
method
The computer will check for a valueOf()
method in the mySpecialCar
object instance. But it will find none, so it moves to the next scope to continue its quest.
2. Check if mySpecialCar
’s dunder proto has a valueOf()
method
Since valueOf()
is not in the mySpecialCar
object, JavaScript will check if mySpecialCar
’s dunder proto has a valueOf()
method as one of its properties.
In other words, the computer looks for valueOf()
in mySpecialCar.[[Prototype]]
. But it will find none there either, so it climbs up the ladder to the next scope.
3. Check if mySpecialCar
’s dunder proto’s [[Prototype]]
has a valueOf()
method
JavaScript will check if the dunder proto of mySpecialCar
’s [[Prototype]]
has a valueOf()
method as one of its properties.
In other words, the computer looks for valueOf()
in mySpecialCar.[[Prototype]].[[Prototype]]
. And it finds it there!!!
Therefore, the mySpecialCar
instance object will inherit the valueOf()
method from Object.prototype
.
As a result, the mySpecialCar.valueOf()
invocation will successfully return mySpecialCar
’s value ({wheel: 35, gearbox: 1, mirrors: 7}
).
Here’s an example:
JavaScript’s inheritance system is sometimes called “prototype chain” or “prototypal inheritance.”
Prototypal inheritance refers to objects inheriting a constructor’s prototype
.
In other words, you can say that mySpecialCar
prototypically inherits the valueOf()
method from the Object()
constructor’s prototype
property.
TLDR
The main gist of the walk-through above is that JavaScript does not limit its search for a feature to an object instance’s scope only. Instead, it also checks the following environments:
- The object instance’s dunder proto.
- The dunder proto of the object instance’s dunder proto.
- And so on till the computer finds a matching feature or the search reaches the end of the prototype chain.
A slick computer trick that makes mistakes disappear
What Scope Ends JavaScript’s Prototype Chain?
The Object()
constructor function’s scope ends JavaScript’s prototype chain.
In other words, Object()
has no dunder proto. It sits at the top of the JavaScript prototype chain.
Below are examples of the prototype chain in JavaScript.
What ends an Object
instance’s prototype chain?
The snippet above returned null
because Object()
is the prototype chain’s final link.
myObject
inheritedObject()
’sprototype
(myObject.[[Prototype]]
).Object()
inherits no constructor’sprototype
. So,myObject.[[Prototype]].[[Prototype]]
’s value isnull
.
Therefore, myObject
’s prototype chain looks like this:
What ends an Array
instance’s prototype chain?
The snippet above returned null
because Object()
is the prototype chain’s final link.
myArray
inheritedArray()
’sprototype
(myArray.[[Prototype]]
).Array()
inheritedObject()
’sprototype
(myArray.[[Prototype]].[[Prototype]]
).Object()
inherits no constructor’sprototype
. So,myArray.[[Prototype]].[[Prototype]].[[Prototype]]
’s value isnull
.
Therefore, myArray
’s prototype chain looks like this:
What ends a Function
instance’s prototype chain?
The snippet above returned null
because Object()
is the prototype chain’s final link.
myFunction
inheritedFunction()
’sprototype
(myFunction.[[Prototype]]
).Function()
inheritedObject()
’sprototype
(myFunction.[[Prototype]].[[Prototype]]
).Object()
inherits no constructor’sprototype
. So,myFunction.[[Prototype]].[[Prototype]].[[Prototype]]
’s value isnull
.
Therefore, myFunction
’s prototype chain looks like this:
What ends the wifeProfile
instance’s prototype chain?
The snippet above returned null
because Object()
is the prototype chain’s final link.
wifeProfile
inheritedbestFriend
as its dunder proto (wifeProfile.[[Prototype]]
).bestFriend
inheritedmyName
as its dunder proto (wifeProfile.[[Prototype]].[[Prototype]]
).myName
inheritedObject()
’sprototype
(myName.[[Prototype]].[[Prototype]].[[Prototype]]
).Object()
inherits no constructor’sprototype
. So,myFunction.[[Prototype]].[[Prototype]].[[Prototype]].[[Prototype]]
’s value isnull
.
Therefore, wifeProfile
’s prototype chain looks like this:
The four examples above show that JavaScript’s inheritance chain ends at the Object()
constructor function’s scope.
Let’s use a diagram to illustrate the prototype chain.
Design and develop at the same time
The JavaScript prototype chain diagram
The code below describes mySpecialCar
’s prototype chain.
The snippet above returned null
because Object()
is the prototype chain’s final link.
mySpecialCar
inheritedMyCar
’sprototype
(mySpecialCar.[[Prototype]]
).MyCar
inheritedObject()
’sprototype
(mySpecialCar.[[Prototype]].[[Prototype]]
).Object()
inherits no constructor’sprototype
. So,mySpecialCar.[[Prototype]].[[Prototype]].[[Prototype]]
’s value isnull
.
Therefore, mySpecialCar
’s prototype chain looks like this:
Below is the diagram illustrating mySpecialCar
’s prototype chain.
The diagram above shows that the Object()
constructor function is the prototype chain’s last link—it inherits nothing (null
) from any other constructor.
Although we used a constructor function in the illustration above, the diagram works for all JavaScript objects—regardless of how you’ve created them.
Suppose you wish to set an object’s dunder proto during its creation rather than alter its prototype chain afterward. How can you do this? Let’s find out.
How to Specify an Object’s Dunder Proto at Creation Time
There are two main ways to specify an object’s dunder proto ([[Prototype]]
) at creation time (when you are creating the object).
- Use the
Object.create()
method. - Use
__proto__
as an object literal’s own property.
Let’s discuss the two techniques now.
How to use the Object.create()
method to specify an object’s dunder proto
The Object.create()
method does the following:
- It creates a new object.
- It makes its first argument the newly created object’s dunder proto.
Therefore, you can use Object.create()
to specify an object’s dunder proto like so:
The snippet above used Object.create()
to create a new object and assign myName
as the newly created object’s dunder proto.
Let’s see the second way to specify an object’s dunder proto at creation time.
Design in Figma, launch in Webflow
How to use __proto__
to specify an object’s dunder proto
Instead of the Object.create()
method, you can define a __proto__
property directly in an object literal like so:
The snippet above used __proto__
as an own property to assign myName
as the newly created object’s dunder prototype.
__proto__
Own Property vs. __proto__
Prototype Accessor: What’s the Difference?
To use __proto__
as an own property and to use it as a prototype accessor works in different ways. The sections below discuss the main distinctions between them.
What is a __proto__
own property?
A __proto__
own property allows you to define an object literal’s dunder proto at creation time.
Here’s an example:
The snippet above used __proto__
as the object literal ({}
)‘s own property.
In this instance, __proto__
is standardized, optimized, and not deprecated. You can freely use it in your codebase. Its performance may even be better than the Object.create()
method.
What is a __proto__
prototype accessor?
A __proto__
accessor allows you to access an object’s inherited prototype.
Here’s an example:
The snippet above used __proto__
to access the prototype bestFriend
inherited from its constructor.
In this instance, __proto__
is non-standard, deprecated, and no longer recommended. A better alternative is to use Object.getPrototypeOf()
like so:
Suppose you wish to check whether a specific prototype
exists in an object’s prototype chain. How can you do this? Let’s find out.
How to Confirm If a Specific prototype
Exists in an Object’s Prototype Chain
Use the isPrototypeOf()
method to check if a specific prototype
exists in an object’s prototype chain.
Example 1: How to check if Object.prototype
is in MyCar
’s prototype chain
The snippet above returned true
because MyCar
inherited the global Object()
’s prototype
from Function.prototype
. Therefore, Object
’s prototype
is one of MyCar
’s dunder protos.
In other words,
Learn Flexbox with Images
Example 2: How to check if two given prototypes exist in mySpecialCar
’s prototype chain
The snippet above returned true
because mySpecialCar
inherited MyCar
’s prototype
. Therefore, MyCar.prototype
and Object.prototype
are part of MyCar
’s dunder protos.
Example 3: How to check if MyCar.prototype
is in mySpecialCar
’s prototype chain
The snippet above returned true
because mySpecialCar
inherited MyCar
’s prototype
from WifeCar.prototype
. Therefore, MyCar
’s prototype
is one of mySpecialCar
’s dunder protos.
Now that you know what prototype is, we can discuss why it is an essential JavaScript feature.
Why Is Prototype Essential in JavaScript?
Prototype helps you optimize your code by allowing objects to inherit one another’s features.
In other words, a JavaScript prototype is the chain linking one object to another object.
For instance, suppose you want users to use a getInfo()
method to access some books’ data. In that case, you can add the method as each book’s own property like so:
The snippet above works—but it is subpar. Repeating the same method in each object is redundant and unnecessary. A better way to lower memory usage is to set getInfo()
as each book’s dunder proto on creation.
Here’s an example:
You can see that we now have only one getInfo()
method rather than three for the three books.
Although the code above is more performant than using the getInfo()
method as each book’s own feature, you can better optimize memory usage by using a constructor function’s prototype
property to predefine each book’s dunder proto.
Here’s an example:
The snippet above created each book instance from the Book()
constructor function, which has a getInfo()
method predefined in its prototype
.
Therefore, every new book object you create from the Book()
constructor will inherit the getInfo()
method automatically, which reduces the memory required to create new books.