In JavaScript, the new keyword is used to create an instance of a user-defined object type or one of the built-in object types that has a constructor function. When you use new with a constructor function, it performs the following steps:
Creates a new empty object.
Sets the
[[prototype]]of the new object to the.prototypeproperty of the constructor function.Binds
thisto the new object within the constructor function.Executes the constructor function with the provided arguments.
Returns the new object unless the constructor function returns a non-primitive value (an object or a function), in which case that value is returned instead.
Here is an example to illustrate how the new keyword works:
Example: Using new with a Constructor Function
// Define a constructor function
function Person(name, age) {
this.name = name;
this.age = age;
// Method to greet
this.greet = function() {
console.log(`Hello, my name is ${this.name} and I am ${this.age} years
old.`);
};
}
// Use `new` to create an instance of Person
const john = new Person('John', 30);
const jane = new Person('Jane', 25);
// Call the greet method on the instances
john.greet();
// Output: Hello, my name is John and I am 30 years old.
jane.greet();
// Output: Hello, my name is Jane and I am 25 years old.How new Works in Steps
Create a new object:
let instance = {}; // new empty objectSet the prototype:
instance.__proto__ = Person.prototype; // Set the prototypeBind
thisand execute the constructor:
Person.call(instance, 'John', 30);
// Execute the constructor with `this` bound to `instance`Since
.call()setsthis = instance, every line inside the constructor becomes:this.name = name; → instance.name = "John" this.age = age; → instance.age = 30 this.greet = ... → instance.greet = function() { ... }The constructor does not return the object.
It only fills
instancewith values.After that, the “new” mechanism returns the
instanceobject.instance = { name: "John", age: 30, greet: function() { ... } }
Return the new object:
return instance;<div class="infographic-newsteps">
<style>
.infographic-newsteps {
--ink: #1a1a1a;
--ink-soft: #5c5c5c;
--paper: #ffffff;
--paper-alt: #f0ece4;
--accent: #2563eb;
--accent-soft:#e3ebfd;
--line: #ddd6c9;
--good: #1a8a5f;
--good-soft: #e1f2ea;
box-sizing: border-box;
max-width: 880px;
margin: 0 auto;
font-family: 'Inter', system-ui, sans-serif;
color: var(--ink);
background: var(--paper);
overflow-x: hidden;
}
.infographic-newsteps[data-theme="dark"] {
--ink: #e8e6e1;
--ink-soft: #9a968c;
--paper: #121212;
--paper-alt: #1e1e26;
--accent: #5b8def;
--accent-soft:#202942;
--line: #2c313d;
--good: #4fbf8f;
--good-soft: #16281f;
}
.infographic-newsteps * { box-sizing: border-box; }
.infographic-newsteps h1 { font-family: 'Fraunces', Georgia, serif; font-weight: 600; margin: 0; }
.infographic-newsteps p { margin: 0; }
.infographic-newsteps button { font-family: inherit; }
.nw-wrap { padding: clamp(1.25rem, 5vw, 2.5rem) clamp(1.1rem, 5vw, 3rem) 2rem; }
.nw-hero { text-align: center; margin-bottom: 1.3rem; }
.nw-hero h1 { font-size: clamp(1.35rem, 4.5vw, 1.85rem); }
.nw-hero p { color: var(--ink-soft); margin-top: 0.45rem; font-size: 0.85rem; }
/* traced code block */
.nw-code { border: 1.5px solid var(--line); background: var(--paper-alt); padding: 0.7rem 0.9rem; font-family: 'IBM Plex Mono', monospace; font-size: 0.72rem; line-height: 1.9; margin-bottom: 1.5rem; }
.nw-code .ln { display: flex; gap: 0.6rem; padding: 0.05rem 0.3rem; border-radius: 3px; transition: background 0.3s ease, color 0.3s ease; color: var(--ink-soft); }
.nw-code .ln .num { opacity: 0.5; width: 1.1em; flex-shrink: 0; }
.nw-code .ln.is-active { background: var(--accent-soft); color: var(--accent); font-weight: 600; }
.nw-code .ln.is-done { color: var(--ink); }
/* diagram */
.nw-stage { display: flex; flex-direction: column; align-items: center; }
.nw-proto { width: min(230px, 100%); text-align: center; border: 1.5px solid var(--line); background: var(--paper-alt); padding: 0.5rem 0.7rem; }
.nw-proto .nw-name { font-family: 'IBM Plex Mono', monospace; font-weight: 700; font-size: 0.74rem; }
.nw-proto .nw-sub { font-size: 0.6rem; color: var(--ink-soft); margin-top: 0.1rem; }
.nw-link { width: 2px; height: 32px; background: var(--line); position: relative; }
.nw-link-fill { position: absolute; left: 0; top: 0; width: 2px; height: 0%; background: var(--accent); transition: height 0.85s ease; }
.nw-link-label { font-family: 'IBM Plex Mono', monospace; font-size: 0.58rem; text-align: center; margin: 0.15rem 0; color: var(--ink-soft); opacity: 0.5; transition: opacity 0.5s ease, color 0.5s ease; }
.nw-link-label.is-lit { opacity: 1; color: var(--accent); font-weight: 600; }
.nw-instance {
width: min(280px, 100%); text-align: left; border: 1.5px solid var(--line); background: var(--paper-alt);
padding: 0.65rem 0.8rem; position: relative; transition: border-color 0.4s ease, background 0.4s ease;
}
.nw-instance .nw-title { font-family: 'IBM Plex Mono', monospace; font-weight: 700; font-size: 0.78rem; text-align: center; margin-bottom: 0.4rem; }
.nw-field { display: flex; justify-content: space-between; font-family: 'IBM Plex Mono', monospace; font-size: 0.68rem; padding: 0.15rem 0; opacity: 0.25; transform: translateX(-6px); transition: opacity 0.55s ease, transform 0.55s ease, color 0.55s ease; }
.nw-field.is-set { opacity: 1; transform: translateX(0); color: var(--good); font-weight: 600; }
.nw-field .k { color: var(--ink-soft); }
.nw-field.is-set .k { color: var(--good); }
.nw-empty-tag { text-align: center; font-family: 'IBM Plex Mono', monospace; font-size: 0.68rem; color: var(--ink-soft); opacity: 1; transition: opacity 0.3s ease; }
.nw-instance.has-fields .nw-empty-tag { opacity: 0; height: 0; overflow: hidden; }
.nw-returned { position: absolute; top: -10px; right: -10px; display: flex; align-items: center; gap: 0.25rem; font-size: 0.6rem; font-weight: 700; color: var(--good); background: var(--good-soft); border: 1.5px solid var(--good); padding: 0.15rem 0.4rem; opacity: 0; transform: scale(0.7); transition: opacity 0.5s ease, transform 0.5s ease; }
.nw-returned.is-shown { opacity: 1; transform: scale(1); }
.nw-returned svg { width: 11px; height: 11px; stroke: var(--good); }
.nw-play { display: block; margin: 1.2rem auto 0; border: none; background: var(--accent); color: #fff; padding: 0.55rem 1.3rem; font-size: 0.8rem; font-weight: 600; cursor: pointer; }
.nw-play:active { transform: scale(0.96); }
.nw-play:disabled { opacity: 0.45; cursor: default; }
.nw-note { text-align: center; font-size: 0.78rem; color: var(--ink-soft); margin-top: 1.4rem; padding-top: 1rem; border-top: 1px dashed var(--line); }
.nw-note strong { color: var(--ink); }
@media (prefers-reduced-motion: reduce) {
.infographic-newsteps *, .infographic-newsteps *::before, .infographic-newsteps *::after {
animation-duration: 0.001ms !important; transition-duration: 0.001ms !important;
}
}
</style>
<div class="nw-wrap">
<div class="nw-hero">
<h1>What "new" actually does</h1>
<p>Four plain steps, no magic. Press play and trace them.</p>
</div>
<div class="nw-code" id="nwCode">
<div class="ln" data-step="1"><span class="num">1</span><span>let instance = {}</span></div>
<div class="ln" data-step="2"><span class="num">2</span><span>instance.__proto__ = Person.prototype</span></div>
<div class="ln" data-step="3"><span class="num">3</span><span>Person.call(instance, "John", 30)</span></div>
<div class="ln" data-step="4"><span class="num">4</span><span>return instance</span></div>
</div>
<div class="nw-stage">
<div class="nw-proto">
<div class="nw-name">Person.prototype</div>
<div class="nw-sub">greet, constructor…</div>
</div>
<div class="nw-link">
<div class="nw-link-fill" id="nwFill"></div>
</div>
<div class="nw-link-label" id="nwLinkLabel">__proto__</div>
<div class="nw-instance" id="nwInstance">
<div class="nw-returned" id="nwReturned">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M20 6 9 17l-5-5"/></svg>
returned
</div>
<div class="nw-title">instance</div>
<div class="nw-empty-tag" id="nwEmptyTag">{ }</div>
<div class="nw-field" id="fName"><span class="k">name:</span><span>"John"</span></div>
<div class="nw-field" id="fAge"><span class="k">age:</span><span>30</span></div>
<div class="nw-field" id="fGreet"><span class="k">greet:</span><span>ƒ () {…}</span></div>
</div>
</div>
<button class="nw-play" id="nwPlay" type="button">new Person("John", 30)</button>
<p class="nw-note"><strong>Person</strong> never returns the object itself — it only fills in <strong>instance</strong> using <strong>.call()</strong>. The "new" mechanism hands that object back at the end.</p>
</div>
</div>
<script>
(function () {
const wrapper = document.currentScript.closest('.infographic-newsteps')
|| document.querySelector('.infographic-newsteps');
const bodyAttr = document.body.getAttribute('data-darkmode');
let dark;
if (bodyAttr === 'true') { dark = true; }
else if (bodyAttr === 'false') { dark = false; }
else {
const match = document.cookie.match(/(?:^|;\s*)darkMode=([^;]+)/);
dark = match ? match[1] === 'true' : false;
}
if (dark) wrapper.setAttribute('data-theme', 'dark');
const playBtn = wrapper.querySelector('#nwPlay');
const lines = wrapper.querySelectorAll('.nw-code .ln');
const fill = wrapper.querySelector('#nwFill');
const linkLabel = wrapper.querySelector('#nwLinkLabel');
const instance = wrapper.querySelector('#nwInstance');
const emptyTag = wrapper.querySelector('#nwEmptyTag');
const fields = [wrapper.querySelector('#fName'), wrapper.querySelector('#fAge'), wrapper.querySelector('#fGreet')];
const returned = wrapper.querySelector('#nwReturned');
function setActiveLine(step) {
lines.forEach(l => {
const s = Number(l.dataset.step);
l.classList.toggle('is-active', s === step);
l.classList.toggle('is-done', s < step);
});
}
playBtn.addEventListener('click', () => {
playBtn.disabled = true;
lines.forEach(l => l.classList.remove('is-active', 'is-done'));
fill.style.transition = 'none';
fill.style.height = '0%';
void fill.offsetWidth;
fill.style.transition = 'height 0.5s ease';
linkLabel.classList.remove('is-lit');
instance.classList.remove('has-fields');
fields.forEach(f => f.classList.remove('is-set'));
returned.classList.remove('is-shown');
// step 1: empty instance
setTimeout(() => setActiveLine(1), 150);
// step 2: proto link
setTimeout(() => {
setActiveLine(2);
fill.style.height = '100%';
linkLabel.classList.add('is-lit');
}, 1200);
// step 3: fields fill via call()
setTimeout(() => setActiveLine(3), 2400);
setTimeout(() => { instance.classList.add('has-fields'); fields[0].classList.add('is-set'); }, 2650);
setTimeout(() => fields[1].classList.add('is-set'), 3150);
setTimeout(() => fields[2].classList.add('is-set'), 3650);
// step 4: return
setTimeout(() => {
setActiveLine(4);
returned.classList.add('is-shown');
}, 4450);
setTimeout(() => { playBtn.disabled = false; }, 4950);
});
})();
</script>Key Points
newis used with constructor functions and classes to create instances.The new object’s prototype is set to the constructor’s prototype.
thisinside the constructor function refers to the new object.The constructor function initializes the new object.
The
newkeyword is essential for ensuring the correct creation and setup of the new object. Withoutnew, the function would not behave as a constructor andthiswould not refer to a new instance.