this

  • Revision slug: JavaScript/Reference/Operators/this
  • Revision title: this
  • Revision id: 27163
  • Created:
  • Creator: webXL
  • Is current revision? No
  • Comment "As a constructor" example, last line: C2.a should be o.a; 3 words added, 1 words removed

Revision Content

Global context

In the global context, in strict mode or not, this refers to the global object.

// In a web browser, the window object is also the global object:
this === window; // true
this.document === document; // true

this.a = 37;
window.a; // 37

Function context

The this value depends on how the function is being used.

Simple call

function f1(){
  return this;
}

f1() === window; // global object


function f2(){
  "use strict"; // see strict mode
  return this;
}

f2() === undefined;

As an object method

In this case, this is bound to the object the method is called on.

function azerty(){
  return this.prop;
}

var o = {f: azerty, prop: 37};
o.f(); // f's 'this' is bound to o. '37' is returned

o.b = {g: azerty};
o.b.g(); // o.b doesn't have a 'prop' property. 'undefined' is returned

... on the prototype chain

If the method is on the prototype chain, this refers to the receiver object.

var o = {f:function(){return this.a+this.b;}};
var p = Object.create(o);
p.a = 1;
p.b = 4;

console.log(p.f()); // 5

In this example, the object in the variable p doesn't have an f function. It inherits it from its prototype object. Nevertheless, in this context, this refers to the object in the variable p. This is one interesting feature in terms of prototypal inheritance in JavaScript.

As a constructor

When a function is used as a constructor (with the new keyword), this is bound to a fresh object.

/* 
** Commented code is implicitely added to the function when called by the engine as a constructor 
*/
function MyConstructor(){
  // var this = Object.create(MyConstructor.prototype); // In user code, setting 'this' always throws a ReferenceError
  ... actual function body code ...
  ... can set properties to 'this' ...
  // if what is returned by the function body is an object, return it.
  // return the object in 'this' otherwise
}

// ... //

function C(){
  this.a = 37;
}

var o = new C();
o.a; // 37


function C2(){
  this.a = 37;
  return {a:38};
}

o = new C2();
o.a; // 38. because what is returned is an object. In this case, 'this' is just useless.

call and apply

In the case where you have a function using the this keyword in its body and you want to set the value yourself, you can do it by using call or apply

function add(c, d){
  return this.a + this.b + c + d;
}

var o = {a:1, b:3};

add.call(o, 5, 7); // 1+3+5+7 = 16
add.apply(o, [10, 20]); // 1+3+10+20 = 34

Bound functions

ECMAScript 5 introduced Function.prototype.bind. Calling f.bind(someObject) creates a new function with the same body and scope than f but which this is bound to the first argument of bind regardless of how the function is being used.

function f(){
  return this.a;
}

var g = f.bind({a:"azerty"});
console.log(g()); // azerty

var o = {a:37, f:f, g:g};
console.log(o.f(), o.g()); // 37, azerty

As a getter or setter

Functions used as getter or setter have their this bound to the object from which the property is being set or gotten.

function modulus(){
  return Math.sqrt(this.re*this.re + this.im*this.im);
}

var o = {
  re:1,
  im:-1,
  get phase(){
    return Math.atan2(this.im, this.re);
  }
};

Object.defineProperty(o, 'modulus', {get: modulus, enumerable:true, configurable:true});

console.log(o.phase, o.modulus); // -0.78, 1.4142

As a DOM event handler

When a function is used as an event handler, this is bound to the element the event fired from.

// Wheneven you click on an element, il will become blue
function bluify(e){
  console.log(this === e.currentTarget); // Always true
  console.log(this === e.target);        // true when currentTarget and target are the same object
  this.style.backgroundColor = '#A5D9F3';
}

var elements = document.getElementsByTagName('*');

for(var i=0 ; i<elements.length ; i++){
  elements[i].addEventListener('click', bluify, false);
}

Revision Source

<h2>Global context</h2>
<p>In the global context, in strict mode or not, <code>this</code> refers to the global object.</p>
<pre class="brush: js">// In a web browser, the window object is also the global object:
this === window; // true
this.document === document; // true

this.a = 37;
window.a; // 37
</pre>
<h2>Function context</h2>
<p>The <code>this</code> value depends on how the function is being used.</p>
<h3>Simple call</h3>
<pre class="brush: js">function f1(){
  return this;
}

f1() === window; // global object


function f2(){
  "use strict"; // see strict mode
  return this;
}

f2() === undefined;
</pre>
<h3>As an object method</h3>
<p>In this case, <code>this</code> is bound to the object the method is called on.</p>
<pre class="brush: js">function azerty(){
  return this.prop;
}

var o = {f: azerty, prop: 37};
o.f(); // f's 'this' is bound to o. '37' is returned

o.b = {g: azerty};
o.b.g(); // o.b doesn't have a 'prop' property. 'undefined' is returned
</pre>
<h4>... on the prototype chain</h4>
<p>If the method is on the prototype chain, <code>this</code> refers to the receiver object.</p>
<pre class="brush: js">var o = {f:function(){return this.a+this.b;}};
var p = Object.create(o);
p.a = 1;
p.b = 4;

console.log(p.f()); // 5
</pre>
<p>In this example, the object in the variable <code>p</code> doesn't have an <code>f</code> function. It inherits it from its prototype object. Nevertheless, in this context, <code>this</code> refers to the object in the variable <code>p</code>. This is one interesting feature in terms of prototypal inheritance in JavaScript.</p>
<h3>As a constructor</h3>
<p>When a function is used as a constructor (with the <code>new</code> keyword), this is bound to a fresh object.</p>
<pre class="brush: js">/* 
** Commented code is implicitely added to the function when called by the engine as a constructor 
*/
function MyConstructor(){
  // var this = Object.create(MyConstructor.prototype); // In user code, setting 'this' always throws a ReferenceError
  ... actual function body code ...
  ... can set properties to 'this' ...
  // if what is returned by the function body is an object, return it.
  // return the object in 'this' otherwise
}

// ... //

function C(){
  this.a = 37;
}

var o = new C();
o.a; // 37


function C2(){
  this.a = 37;
  return {a:38};
}

o = new C2();
o.a; // 38. because what is returned is an object. In this case, 'this' is just useless.
</pre>
<h3><code>call</code> and <code>apply</code></h3>
<p>In the case where you have a function using the <code>this</code> keyword in its body and you want to set the value yourself, you can do it by using <code>call</code> or <code>apply</code></p>
<pre class="brush: js">function add(c, d){
  return this.a + this.b + c + d;
}

var o = {a:1, b:3};

add.call(o, 5, 7); // 1+3+5+7 = 16
add.apply(o, [10, 20]); // 1+3+10+20 = 34
</pre>
<h3>Bound functions</h3>
<p>ECMAScript 5 introduced <code><a href="/en/JavaScript/Reference/Global_Objects/Function/bind" title="en/JavaScript/Reference/Global Objects/Function/bind">Function.prototype.bind</a></code>. Calling <code>f.bind(someObject)</code> creates a new function with the same body and scope than <code>f</code> but which <code>this</code> is bound to the first argument of <code>bind</code> regardless of how the function is being used.</p>
<pre class="brush: js">function f(){
  return this.a;
}

var g = f.bind({a:"azerty"});
console.log(g()); // azerty

var o = {a:37, f:f, g:g};
console.log(o.f(), o.g()); // 37, azerty
</pre>
<h3>As a getter or setter</h3>
<p>Functions used as getter or setter have their <code>this</code> bound to the object from which the property is being set or gotten.</p>
<pre class="brush: js">function modulus(){
  return Math.sqrt(this.re*this.re + this.im*this.im);
}

var o = {
  re:1,
  im:-1,
  get phase(){
    return Math.atan2(this.im, this.re);
  }
};

Object.defineProperty(o, 'modulus', {get: modulus, enumerable:true, configurable:true});

console.log(o.phase, o.modulus); // -0.78, 1.4142
</pre>
<h3>As a DOM event handler</h3>
<p>When a function is used as an event handler, <code>this</code> is bound to the element the event fired from.</p>
<pre class="brush: js">// Wheneven you click on an element, il will become blue
function bluify(e){
  console.log(this === e.currentTarget); // Always true
  console.log(this === e.target);        // true when currentTarget and target are the same object
  this.style.backgroundColor = '#A5D9F3';
}

var elements = document.getElementsByTagName('*');

for(var i=0 ; i&lt;elements.length ; i++){
  elements[i].addEventListener('click', bluify, false);
}
</pre>
Revert to this revision