Related
I am looking to find a clear explanation of what the "this" keyword does, and how to use it correctly.
It seems to behave strangely, and I don't fully understand why.
How does this work and when should it be used?
this is a keyword in JavaScript that is a property of an execution context. Its main use is in functions and constructors.
The rules for this are quite simple (if you stick to best practices).
Technical description of this in the specification
The ECMAScript standard defines this via the abstract operation (abbreviated AO) ResolveThisBinding:
The [AO] ResolveThisBinding […] determines the binding of the keyword this using the LexicalEnvironment of the running execution context. [Steps]:
Let envRec be GetThisEnvironment().
Return ? envRec.GetThisBinding().
Global Environment Records, module Environment Records, and function Environment Records each have their own GetThisBinding method.
The GetThisEnvironment AO finds the current running execution context’s LexicalEnvironment and finds the closest ascendant Environment Record (by iteratively accessing their [[OuterEnv]] properties) which has a this binding (i.e. HasThisBinding returns true). This process ends in one of the three Environment Record types.
The value of this often depends on whether code is in strict mode.
The return value of GetThisBinding reflects the value of this of the current execution context, so whenever a new execution context is established, this resolves to a distinct value. This can also happen when the current execution context is modified. The following subsections list the five cases where this can happen.
You can put the code samples in the AST explorer to follow along with specification details.
1. Global execution context in scripts
This is script code evaluated at the top level, e.g. directly inside a <script>:
<script>
// Global context
console.log(this); // Logs global object.
setTimeout(function(){
console.log("Not global context");
});
</script>
When in the initial global execution context of a script, evaluating this causes GetThisBinding to take the following steps:
The GetThisBinding concrete method of a global Environment Record envRec […] [does this]:
Return envRec.[[GlobalThisValue]].
The [[GlobalThisValue]] property of a global Environment Record is always set to the host-defined global object, which is reachable via globalThis (window on Web, global on Node.js; Docs on MDN). Follow the steps of InitializeHostDefinedRealm to learn how the [[GlobalThisValue]] property comes to be.
2. Global execution context in modules
Modules have been introduced in ECMAScript 2015.
This applies to modules, e.g. when directly inside a <script type="module">, as opposed to a simple <script>.
When in the initial global execution context of a module, evaluating this causes GetThisBinding to take the following steps:
The GetThisBinding concrete method of a module Environment Record […] [does this]:
Return undefined.
In modules, the value of this is always undefined in the global context. Modules are implicitly in strict mode.
3. Entering eval code
There are two kinds of eval calls: direct and indirect. This distinction exists since the ECMAScript 5th edition.
A direct eval call usually looks like eval(…); or (eval)(…); (or ((eval))(…);, etc.).1 It’s only direct if the call expression fits a narrow pattern.2
An indirect eval call involves calling the function reference eval in any other way. It could be eval?.(…), (…, eval)(…), window.eval(…), eval.call(…,…), etc. Given const aliasEval1 = eval; window.aliasEval2 = eval;, it would also be aliasEval1(…), aliasEval2(…). Separately, given const originalEval = eval; window.eval = (x) => originalEval(x);, calling eval(…) would also be indirect.
See chuckj’s answer to “(1, eval)('this') vs eval('this') in JavaScript?” and Dmitry Soshnikov’s ECMA-262-5 in detail – Chapter 2: Strict Mode (archived) for when you might use an indirect eval() call.
PerformEval executes the eval code. It creates a new declarative Environment Record as its LexicalEnvironment, which is where GetThisEnvironment gets the this value from.
Then, if this appears in eval code, the GetThisBinding method of the Environment Record found by GetThisEnvironment is called and its value returned.
And the created declarative Environment Record depends on whether the eval call was direct or indirect:
In a direct eval, it will be based on the current running execution context’s LexicalEnvironment.
In an indirect eval, it will be based on the [[GlobalEnv]] property (a global Environment Record) of the Realm Record which executed the indirect eval.
Which means:
In a direct eval, the this value doesn’t change; it’s taken from the lexical scope that called eval.
In an indirect eval, the this value is the global object (globalThis).
What about new Function? — new Function is similar to eval, but it doesn’t call the code immediately; it creates a function. A this binding doesn’t apply anywhere here, except when the function is called, which works normally, as explained in the next subsection.
4. Entering function code
Entering function code occurs when calling a function.
There are four categories of syntax to invoke a function.
The EvaluateCall AO is performed for these three:3
Normal function calls
Optional chaining calls
Tagged templates
And EvaluateNew is performed for this one:3
Constructor invocations
The actual function call happens at the Call AO, which is called with a thisValue determined from context; this argument is passed along in a long chain of call-related calls. Call calls the [[Call]] internal slot of the function. This calls PrepareForOrdinaryCall where a new function Environment Record is created:
A function Environment Record is a declarative Environment Record that is used to represent the top-level scope of a function and, if the function is not an ArrowFunction, provides a this binding. If a function is not an ArrowFunction function and references super, its function Environment Record also contains the state that is used to perform super method invocations from within the function.
In addition, there is the [[ThisValue]] field in a function Environment Record:
This is the this value used for this invocation of the function.
The NewFunctionEnvironment call also sets the function environment’s [[ThisBindingStatus]] property.
[[Call]] also calls OrdinaryCallBindThis, where the appropriate thisArgument is determined based on:
the original reference,
the kind of the function, and
whether or not the code is in strict mode.
Once determined, a final call to the BindThisValue method of the newly created function Environment Record actually sets the [[ThisValue]] field to the thisArgument.
Finally, this very field is where a function Environment Record’s GetThisBinding AO gets the value for this from:
The GetThisBinding concrete method of a function Environment Record envRec […] [does this]:
[…]
3. Return envRec.[[ThisValue]].
Again, how exactly the this value is determined depends on many factors; this was just a general overview. With this technical background, let’s examine all the concrete examples.
Arrow functions
When an arrow function is evaluated, the [[ThisMode]] internal slot of the function object is set to “lexical” in OrdinaryFunctionCreate.
At OrdinaryCallBindThis, which takes a function F:
Let thisMode be F.[[ThisMode]].
If thisMode is lexical, return NormalCompletion(undefined).
[…]
which just means that the rest of the algorithm which binds this is skipped. An arrow function does not bind its own this value.
So, what is this inside an arrow function, then? Looking back at ResolveThisBinding and GetThisEnvironment, the HasThisBinding method explicitly returns false.
The HasThisBinding concrete method of a function Environment Record envRec […] [does this]:
If envRec.[[ThisBindingStatus]] is lexical, return false; otherwise, return true.
So the outer environment is looked up instead, iteratively. The process will end in one of the three environments that have a this binding.
This just means that, in arrow function bodies, this comes from the lexical scope of the arrow function, or in other words (from Arrow function vs function declaration / expressions: Are they equivalent / exchangeable?):
Arrow functions don’t have their own this […] binding. Instead, [this identifier is] resolved in the lexical scope like any other variable. That means that inside an arrow function, this [refers] to the [value of this] in the environment the arrow function is defined in (i.e. “outside” the arrow function).
Function properties
In normal functions (function, methods), this is determined by how the function is called.
This is where these “syntax variants” come in handy.
Consider this object containing a function:
const refObj = {
func: function(){
console.log(this);
}
};
Alternatively:
const refObj = {
func(){
console.log(this);
}
};
In any of the following function calls, the this value inside func will be refObj.1
refObj.func()
refObj["func"]()
refObj?.func()
refObj.func?.()
refObj.func``
If the called function is syntactically a property of a base object, then this base will be the “reference” of the call, which, in usual cases, will be the value of this. This is explained by the evaluation steps linked above; for example, in refObj.func() (or refObj["func"]()), the CallMemberExpression is the entire expression refObj.func(), which consists of the MemberExpression refObj.func and the Arguments ().
But also, refObj.func and refObj play three roles, each:
they’re both expressions,
they’re both references, and
they’re both values.
refObj.func as a value is the callable function object; the corresponding reference is used to determine the this binding.
The optional chaining and tagged template examples work very similarly: basically, the reference is everything before the ?.(), before the ``, or before the ().
EvaluateCall uses IsPropertyReference of that reference to determine if it is a property of an object, syntactically. It’s trying to get the [[Base]] property of the reference (which is e.g. refObj, when applied to refObj.func; or foo.bar when applied to foo.bar.baz). If it is written as a property, then GetThisValue will get this [[Base]] property and use it as the this value.
Note: Getters / Setters work the same way as methods, regarding this. Simple properties don’t affect the execution context, e.g. here, this is in global scope:
const o = {
a: 1,
b: this.a, // Is `globalThis.a`.
[this.a]: 2 // Refers to `globalThis.a`.
};
Calls without base reference, strict mode, and with
A call without a base reference is usually a function that isn’t called as a property. For example:
func(); // As opposed to `refObj.func();`.
This also happens when passing or assigning methods, or using the comma operator. This is where the difference between Reference Record and Value is relevant.
Note function j: following the specification, you will notice that j can only return the function object (Value) itself, but not a Reference Record. Therefore the base reference refObj is lost.
const g = (f) => f(); // No base ref.
const h = refObj.func;
const j = () => refObj.func;
g(refObj.func);
h(); // No base ref.
j()(); // No base ref.
(0, refObj.func)(); // Another common pattern to remove the base ref.
EvaluateCall calls Call with a thisValue of undefined here. This makes a difference in OrdinaryCallBindThis (F: the function object; thisArgument: the thisValue passed to Call):
Let thisMode be F.[[ThisMode]].
[…]
If thisMode is strict, let thisValue be thisArgument.
Else,
If thisArgument is undefined or null, then
Let globalEnv be calleeRealm.[[GlobalEnv]].
[…]
Let thisValue be globalEnv.[[GlobalThisValue]].
Else,
Let thisValue be ! ToObject(thisArgument).
NOTE: ToObject produces wrapper objects […].
[…]
Note: step 5 sets the actual value of this to the supplied thisArgument in strict mode — undefined in this case. In “sloppy mode”, an undefined or null thisArgument results in this being the global this value.
If IsPropertyReference returns false, then EvaluateCall takes these steps:
Let refEnv be ref.[[Base]].
Assert: refEnv is an Environment Record.
Let thisValue be refEnv.WithBaseObject().
This is where an undefined thisValue may come from: refEnv.WithBaseObject() is always undefined, except in with statements. In this case, thisValue will be the binding object.
There’s also Symbol.unscopables (Docs on MDN) to control the with binding behavior.
To summarize, so far:
function f1(){
console.log(this);
}
function f2(){
console.log(this);
}
function f3(){
console.log(this);
}
const o = {
f1,
f2,
[Symbol.unscopables]: {
f2: true
}
};
f1(); // Logs `globalThis`.
with(o){
f1(); // Logs `o`.
f2(); // `f2` is unscopable, so this logs `globalThis`.
f3(); // `f3` is not on `o`, so this logs `globalThis`.
}
and:
"use strict";
function f(){
console.log(this);
}
f(); // Logs `undefined`.
// `with` statements are not allowed in strict-mode code.
Note that when evaluating this, it doesn’t matter where a normal function is defined.
.call, .apply, .bind, thisArg, and primitives
Another consequence of step 5 of OrdinaryCallBindThis, in conjunction with step 6.2 (6.b in the spec), is that a primitive this value is coerced to an object only in “sloppy” mode.
To examine this, let’s introduce another source for the this value: the three methods that override the this binding:4
Function.prototype.apply(thisArg, argArray)
Function.prototype. {call, bind} (thisArg, ...args)
.bind creates a bound function, whose this binding is set to thisArg and cannot change again. .call and .apply call the function immediately, with the this binding set to thisArg.
.call and .apply map directly to Call, using the specified thisArg. .bind creates a bound function with BoundFunctionCreate. These have their own [[Call]] method which looks up the function object’s [[BoundThis]] internal slot.
Examples of setting a custom this value:
function f(){
console.log(this);
}
const myObj = {},
g = f.bind(myObj),
h = (m) => m();
// All of these log `myObj`.
g();
f.bind(myObj)();
f.call(myObj);
h(g);
For objects, this is the same in strict and non-strict mode.
Now, try to supply a primitive value:
function f(){
console.log(this);
}
const myString = "s",
g = f.bind(myString);
g(); // Logs `String { "s" }`.
f.call(myString); // Logs `String { "s" }`.
In non-strict mode, primitives are coerced to their object-wrapped form. It’s the same kind of object you get when calling Object("s") or new String("s"). In strict mode, you can use primitives:
"use strict";
function f(){
console.log(this);
}
const myString = "s",
g = f.bind(myString);
g(); // Logs `"s"`.
f.call(myString); // Logs `"s"`.
Libraries make use of these methods, e.g. jQuery sets the this to the DOM element selected here:
$("button").click(function(){
console.log(this); // Logs the clicked button.
});
Constructors, classes, and new
When calling a function as a constructor using the new operator, EvaluateNew calls Construct, which calls the [[Construct]] method. If the function is a base constructor (i.e. not a class extends…{…}), it sets thisArgument to a new object created from the constructor’s prototype. Properties set on this in the constructor will end up on the resulting instance object. this is implicitly returned, unless you explicitly return your own non-primitive value.
A class is a new way of creating constructor functions, introduced in ECMAScript 2015.
function Old(a){
this.p = a;
}
const o = new Old(1);
console.log(o); // Logs `Old { p: 1 }`.
class New{
constructor(a){
this.p = a;
}
}
const n = new New(1);
console.log(n); // Logs `New { p: 1 }`.
Class definitions are implicitly in strict mode:
class A{
m1(){
return this;
}
m2(){
const m1 = this.m1;
console.log(m1());
}
}
new A().m2(); // Logs `undefined`.
super
The exception to the behavior with new is class extends…{…}, as mentioned above. Derived classes do not immediately set their this value upon invocation; they only do so once the base class is reached through a series of super calls (happens implicitly without an own constructor). Using this before calling super is not allowed.
Calling super calls the super constructor with the this value of the lexical scope (the function Environment Record) of the call. GetThisValue has a special rule for super calls. It uses BindThisValue to set this to that Environment Record.
class DerivedNew extends New{
constructor(a, a2){
// Using `this` before `super` results in a ReferenceError.
super(a);
this.p2 = a2;
}
}
const n2 = new DerivedNew(1, 2);
console.log(n2); // Logs `DerivedNew { p: 1, p2: 2 }`.
5. Evaluating class fields
Instance fields and static fields were introduced in ECMAScript 2022.
When a class is evaluated, ClassDefinitionEvaluation is performed, modifying the running execution context. For each ClassElement:
if a field is static, then this refers to the class itself,
if a field is not static, then this refers to the instance.
Private fields (e.g. #x) and methods are added to a PrivateEnvironment.
Static blocks are currently a TC39 stage 3 proposal. Static blocks work the same as static fields and methods: this inside them refers to the class itself.
Note that in methods and getters / setters, this works just like in normal function properties.
class Demo{
a = this;
b(){
return this;
}
static c = this;
static d(){
return this;
}
// Getters, setters, private modifiers are also possible.
}
const demo = new Demo;
console.log(demo.a, demo.b()); // Both log `demo`.
console.log(Demo.c, Demo.d()); // Both log `Demo`.
1: (o.f)() is equivalent to o.f(); (f)() is equivalent to f(). This is explained in this 2ality article (archived). Particularly see how a ParenthesizedExpression is evaluated.
2: It must be a MemberExpression, must not be a property, must have a [[ReferencedName]] of exactly "eval", and must be the %eval% intrinsic object.
3: Whenever the specification says “Let ref be the result of evaluating X.”, then X is some expression that you need to find the evaluation steps for. For example, evaluating a MemberExpression or CallExpression is the result of one of these algorithms. Some of them result in a Reference Record.
4: There are also several other native and host methods that allow providing a this value, notably Array.prototype.map, Array.prototype.forEach, etc. that accept a thisArg as their second argument. Anyone can make their own methods to alter this like (func, thisArg) => func.bind(thisArg), (func, thisArg) => func.call(thisArg), etc. As always, MDN offers great documentation.
Just for fun, test your understanding with some examples
For each code snippet, answer the question: “What is the value of this at the marked line? Why?”.
To reveal the answers, click the gray boxes.
if(true){
console.log(this); // What is `this` here?
}
globalThis. The marked line is evaluated in the initial global execution context.
const obj = {};
function myFun(){
return { // What is `this` here?
"is obj": this === obj,
"is globalThis": this === globalThis
};
}
obj.method = myFun;
console.log(obj.method());
obj. When calling a function as a property of an object, it is called with the this binding set to the base of the reference obj.method, i.e. obj.
const obj = {
myMethod: function(){
return { // What is `this` here?
"is obj": this === obj,
"is globalThis": this === globalThis
};
}
},
myFun = obj.myMethod;
console.log(myFun());
globalThis. Since the function value myFun / obj.myMethod is not called off of an object, as a property, the this binding will be globalThis.
This is different from Python, in which accessing a method (obj.myMethod) creates a bound method object.
const obj = {
myFun: () => ({ // What is `this` here?
"is obj": this === obj,
"is globalThis": this === globalThis
})
};
console.log(obj.myFun());
globalThis. Arrow functions don’t create their own this binding. The lexical scope is the same as the initial global scope, so this is globalThis.
function myFun(){
console.log(this); // What is `this` here?
}
const obj = {
myMethod: function(){
eval("myFun()");
}
};
obj.myMethod();
globalThis. When evaluating the direct eval call, this is obj. However, in the eval code, myFun is not called off of an object, so the this binding is set to the global object.
function myFun() {
// What is `this` here?
return {
"is obj": this === obj,
"is globalThis": this === globalThis
};
}
const obj = {};
console.log(myFun.call(obj));
obj. The line myFun.call(obj); is invoking the special built-in function Function.prototype.call, which accepts thisArg as the first argument.
class MyCls{
arrow = () => ({ // What is `this` here?
"is MyCls": this === MyCls,
"is globalThis": this === globalThis,
"is instance": this instanceof MyCls
});
}
console.log(new MyCls().arrow());
It’s the instance of MyCls. Arrow functions don’t change the this binding, so it comes from lexical scope. Therefore, this is exactly the same as with the class fields mentioned above, like a = this;. Try changing it to static arrow. Do you get the result you expect?
The this keyword behaves differently in JavaScript compared to other languages. In Object Oriented languages, the this keyword refers to the current instance of the class. In JavaScript the value of this is determined by the invocation context of function (context.function()) and where it is called.
1. When used in global context
When you use this in global context, it is bound to global object (window in browser)
document.write(this); //[object Window]
When you use this inside a function defined in the global context, this is still bound to global object since the function is actually made a method of global context.
function f1()
{
return this;
}
document.write(f1()); //[object Window]
Above f1 is made a method of global object. Thus we can also call it on window object as follows:
function f()
{
return this;
}
document.write(window.f()); //[object Window]
2. When used inside object method
When you use this keyword inside an object method, this is bound to the "immediate" enclosing object.
var obj = {
name: "obj",
f: function () {
return this + ":" + this.name;
}
};
document.write(obj.f()); //[object Object]:obj
Above I have put the word immediate in double quotes. It is to make the point that if you nest the object inside another object, then this is bound to the immediate parent.
var obj = {
name: "obj1",
nestedobj: {
name:"nestedobj",
f: function () {
return this + ":" + this.name;
}
}
}
document.write(obj.nestedobj.f()); //[object Object]:nestedobj
Even if you add function explicitly to the object as a method, it still follows above rules, that is this still points to the immediate parent object.
var obj1 = {
name: "obj1",
}
function returnName() {
return this + ":" + this.name;
}
obj1.f = returnName; //add method to object
document.write(obj1.f()); //[object Object]:obj1
3. When invoking context-less function
When you use this inside function that is invoked without any context (i.e. not on any object), it is bound to the global object (window in browser)(even if the function is defined inside the object) .
var context = "global";
var obj = {
context: "object",
method: function () {
function f() {
var context = "function";
return this + ":" +this.context;
};
return f(); //invoked without context
}
};
document.write(obj.method()); //[object Window]:global
Trying it all with functions
We can try above points with functions too. However there are some differences.
Above we added members to objects using object literal notation. We can add members to functions by using this. to specify them.
Object literal notation creates an instance of object which we can use immediately. With function we may need to first create its instance using new operator.
Also in an object literal approach, we can explicitly add members to already defined object using dot operator. This gets added to the specific instance only. However I have added variable to the function prototype so that it gets reflected in all instances of the function.
Below I tried out all the things that we did with Object and this above, but by first creating function instead of directly writing an object.
/*********************************************************************
1. When you add variable to the function using this keyword, it
gets added to the function prototype, thus allowing all function
instances to have their own copy of the variables added.
*********************************************************************/
function functionDef()
{
this.name = "ObjDefinition";
this.getName = function(){
return this+":"+this.name;
}
}
obj1 = new functionDef();
document.write(obj1.getName() + "<br />"); //[object Object]:ObjDefinition
/*********************************************************************
2. Members explicitly added to the function protorype also behave
as above: all function instances have their own copy of the
variable added.
*********************************************************************/
functionDef.prototype.version = 1;
functionDef.prototype.getVersion = function(){
return "v"+this.version; //see how this.version refers to the
//version variable added through
//prototype
}
document.write(obj1.getVersion() + "<br />"); //v1
/*********************************************************************
3. Illustrating that the function variables added by both above
ways have their own copies across function instances
*********************************************************************/
functionDef.prototype.incrementVersion = function(){
this.version = this.version + 1;
}
var obj2 = new functionDef();
document.write(obj2.getVersion() + "<br />"); //v1
obj2.incrementVersion(); //incrementing version in obj2
//does not affect obj1 version
document.write(obj2.getVersion() + "<br />"); //v2
document.write(obj1.getVersion() + "<br />"); //v1
/*********************************************************************
4. `this` keyword refers to the immediate parent object. If you
nest the object through function prototype, then `this` inside
object refers to the nested object not the function instance
*********************************************************************/
functionDef.prototype.nestedObj = { name: 'nestedObj',
getName1 : function(){
return this+":"+this.name;
}
};
document.write(obj2.nestedObj.getName1() + "<br />"); //[object Object]:nestedObj
/*********************************************************************
5. If the method is on an object's prototype chain, `this` refers
to the object the method was called on, as if the method was on
the object.
*********************************************************************/
var ProtoObj = { fun: function () { return this.a } };
var obj3 = Object.create(ProtoObj); //creating an object setting ProtoObj
//as its prototype
obj3.a = 999; //adding instance member to obj3
document.write(obj3.fun()+"<br />");//999
//calling obj3.fun() makes
//ProtoObj.fun() to access obj3.a as
//if fun() is defined on obj3
4. When used inside constructor function.
When the function is used as a constructor (that is when it is called with new keyword), this inside function body points to the new object being constructed.
var myname = "global context";
function SimpleFun()
{
this.myname = "simple function";
}
var obj1 = new SimpleFun(); //adds myname to obj1
//1. `new` causes `this` inside the SimpleFun() to point to the
// object being constructed thus adding any member
// created inside SimipleFun() using this.membername to the
// object being constructed
//2. And by default `new` makes function to return newly
// constructed object if no explicit return value is specified
document.write(obj1.myname); //simple function
5. When used inside function defined on prototype chain
If the method is on an object's prototype chain, this inside such method refers to the object the method was called on, as if the method is defined on the object.
var ProtoObj = {
fun: function () {
return this.a;
}
};
//Object.create() creates object with ProtoObj as its
//prototype and assigns it to obj3, thus making fun()
//to be the method on its prototype chain
var obj3 = Object.create(ProtoObj);
obj3.a = 999;
document.write(obj3.fun()); //999
//Notice that fun() is defined on obj3's prototype but
//`this.a` inside fun() retrieves obj3.a
6. Inside call(), apply() and bind() functions
All these methods are defined on Function.prototype.
These methods allows to write a function once and invoke it in different context. In other words, they allows to specify the value of this which will be used while the function is being executed. They also take any parameters to be passed to the original function when it is invoked.
fun.apply(obj1 [, argsArray]) Sets obj1 as the value of this inside fun() and calls fun() passing elements of argsArray as its arguments.
fun.call(obj1 [, arg1 [, arg2 [,arg3 [, ...]]]]) - Sets obj1 as the value of this inside fun() and calls fun() passing arg1, arg2, arg3, ... as its arguments.
fun.bind(obj1 [, arg1 [, arg2 [,arg3 [, ...]]]]) - Returns the reference to the function fun with this inside fun bound to obj1 and parameters of fun bound to the parameters specified arg1, arg2, arg3,....
By now the difference between apply, call and bind must have become apparent. apply allows to specify the arguments to function as array-like object i.e. an object with a numeric length property and corresponding non-negative integer properties. Whereas call allows to specify the arguments to the function directly. Both apply and call immediately invokes the function in the specified context and with the specified arguments. On the other hand, bind simply returns the function bound to the specified this value and the arguments. We can capture the reference to this returned function by assigning it to a variable and later we can call it any time.
function add(inc1, inc2)
{
return this.a + inc1 + inc2;
}
var o = { a : 4 };
document.write(add.call(o, 5, 6)+"<br />"); //15
//above add.call(o,5,6) sets `this` inside
//add() to `o` and calls add() resulting:
// this.a + inc1 + inc2 =
// `o.a` i.e. 4 + 5 + 6 = 15
document.write(add.apply(o, [5, 6]) + "<br />"); //15
// `o.a` i.e. 4 + 5 + 6 = 15
var g = add.bind(o, 5, 6); //g: `o.a` i.e. 4 + 5 + 6
document.write(g()+"<br />"); //15
var h = add.bind(o, 5); //h: `o.a` i.e. 4 + 5 + ?
document.write(h(6) + "<br />"); //15
// 4 + 5 + 6 = 15
document.write(h() + "<br />"); //NaN
//no parameter is passed to h()
//thus inc2 inside add() is `undefined`
//4 + 5 + undefined = NaN</code>
7. this inside event handlers
When you assign function directly to event handlers of an element, use of this directly inside event handling function refers to the corresponding element. Such direct function assignment can be done using addeventListener method or through the traditional event registration methods like onclick.
Similarly, when you use this directly inside the event property (like <button onclick="...this..." >) of the element, it refers to the element.
However use of this indirectly through the other function called inside the event handling function or event property resolves to the global object window.
The same above behavior is achieved when we attach the function to the event handler using Microsoft's Event Registration model method attachEvent. Instead of assigning the function to the event handler (and the thus making the function method of the element), it calls the function on the event (effectively calling it in global context).
I recommend to better try this in JSFiddle.
<script>
function clickedMe() {
alert(this + " : " + this.tagName + " : " + this.id);
}
document.getElementById("button1").addEventListener("click", clickedMe, false);
document.getElementById("button2").onclick = clickedMe;
document.getElementById("button5").attachEvent('onclick', clickedMe);
</script>
<h3>Using `this` "directly" inside event handler or event property</h3>
<button id="button1">click() "assigned" using addEventListner() </button><br />
<button id="button2">click() "assigned" using click() </button><br />
<button id="button3" onclick="alert(this+ ' : ' + this.tagName + ' : ' + this.id);">used `this` directly in click event property</button>
<h3>Using `this` "indirectly" inside event handler or event property</h3>
<button onclick="alert((function(){return this + ' : ' + this.tagName + ' : ' + this.id;})());">`this` used indirectly, inside function <br /> defined & called inside event property</button><br />
<button id="button4" onclick="clickedMe()">`this` used indirectly, inside function <br /> called inside event property</button> <br />
IE only: <button id="button5">click() "attached" using attachEvent() </button>
8. this in ES6 arrow function
In an arrow function, this will behave like common variables: it will be inherited from its lexical scope. The function's this, where the arrow function is defined, will be the arrow function's this.
So, that's the same behavior as:
(function(){}).bind(this)
See the following code:
const globalArrowFunction = () => {
return this;
};
console.log(globalArrowFunction()); //window
const contextObject = {
method1: () => {return this},
method2: function(){
return () => {return this};
}
};
console.log(contextObject.method1()); //window
const contextLessFunction = contextObject.method1;
console.log(contextLessFunction()); //window
console.log(contextObject.method2()()) //contextObject
const innerArrowFunction = contextObject.method2();
console.log(innerArrowFunction()); //contextObject
Javascript's this
Simple function invocation
Consider the following function:
function foo() {
console.log("bar");
console.log(this);
}
foo(); // calling the function
Note that we are running this in the normal mode, i.e. strict mode is not used.
When running in a browser, the value of this would be logged as window. This is because window is the global variable in a web browser's scope.
If you run this same piece of code in an environment like node.js, this would refer to the global variable in your app.
Now if we run this in strict mode by adding the statement "use strict"; to the beginning of the function declaration, this would no longer refer to the global variable in either of the environments. This is done to avoid confusions in strict mode. this would, in this case just log undefined, because that is what it is, it is not defined.
In the following cases, we would see how to manipulate the value of this.
Calling a function on an object
There are different ways to do this. If you have called native methods in Javascript like forEach and slice, you should already know that the this variable in that case refers to the Object on which you called that function (Note that in javascript, just about everything is an Object, including Arrays and Functions). Take the following code for example.
var myObj = {key: "Obj"};
myObj.logThis = function () {
// I am a method
console.log(this);
}
myObj.logThis(); // myObj is logged
If an Object contains a property which holds a Function, the property is called a method. This method, when called, will always have it's this variable set to the Object it is associated with. This is true for both strict and non-strict modes.
Note that if a method is stored (or rather, copied) in another variable, the reference to this is no longer preserved in the new variable. For example:
// continuing with the previous code snippet
var myVar = myObj.logThis;
myVar();
// logs either of window/global/undefined based on mode of operation
Considering a more commonly practical scenario:
var el = document.getElementById('idOfEl');
el.addEventListener('click', function() { console.log(this) });
// the function called by addEventListener contains this as the reference to the element
// so clicking on our element would log that element itself
The new keyword
Consider a constructor function in Javascript:
function Person (name) {
this.name = name;
this.sayHello = function () {
console.log ("Hello", this);
}
}
var awal = new Person("Awal");
awal.sayHello();
// In `awal.sayHello`, `this` contains the reference to the variable `awal`
How does this work? Well, let's see what happens when we use the new keyword.
Calling the function with the new keyword would immediately initialize an Object of type Person.
The constructor of this Object has its constructor set to Person. Also, note that typeof awal would return Object only.
This new Object would be assigned the prototype of Person.prototype. This means that any method or property in the Person prototype would be available to all instances of Person, including awal.
The function Person itself is now invoked; this being a reference to the newly constructed object awal.
Pretty straightforward, eh?
Note that the official ECMAScript spec nowhere states that such types of functions are actual constructor functions. They are just normal functions, and new can be used on any function. It's just that we use them as such, and so we call them as such only.
Calling functions on Functions: call and apply
So yeah, since functions are also Objects (and in-fact first class variables in Javascript), even functions have methods which are... well, functions themselves.
All functions inherit from the global Function, and two of its many methods are call and apply, and both can be used to manipulate the value of this in the function on which they are called.
function foo () { console.log (this, arguments); }
var thisArg = {myObj: "is cool"};
foo.call(thisArg, 1, 2, 3);
This is a typical example of using call. It basically takes the first parameter and sets this in the function foo as a reference to thisArg. All other parameters passed to call is passed to the function foo as arguments.
So the above code will log {myObj: "is cool"}, [1, 2, 3] in the console. Pretty nice way to change the value of this in any function.
apply is almost the same as call accept that it takes only two parameters: thisArg and an array which contains the arguments to be passed to the function. So the above call call can be translated to apply like this:
foo.apply(thisArg, [1,2,3])
Note that call and apply can override the value of this set by dot method invocation we discussed in the second bullet.
Simple enough :)
Presenting.... bind!
bind is a brother of call and apply. It is also a method inherited by all functions from the global Function constructor in Javascript. The difference between bind and call/apply is that both call and apply will actually invoke the function. bind, on the other hand, returns a new function with the thisArg and arguments pre-set. Let's take an example to better understand this:
function foo (a, b) {
console.log (this, arguments);
}
var thisArg = {myObj: "even more cool now"};
var bound = foo.bind(thisArg, 1, 2);
console.log (typeof bound); // logs `function`
console.log (bound);
/* logs `function () { native code }` */
bound(); // calling the function returned by `.bind`
// logs `{myObj: "even more cool now"}, [1, 2]`
See the difference between the three? It is subtle, but they are used differently. Like call and apply, bind will also over-ride the value of this set by dot-method invocation.
Also note that neither of these three functions do any change to the original function. call and apply would return the value from freshly constructed functions while bind will return the freshly constructed function itself, ready to be called.
Extra stuff, copy this
Sometimes, you don't like the fact that this changes with scope, especially nested scope. Take a look at the following example.
var myObj = {
hello: function () {
return "world"
},
myMethod: function () {
// copy this, variable names are case-sensitive
var that = this;
// callbacks ftw \o/
foo.bar("args", function () {
// I want to call `hello` here
this.hello(); // error
// but `this` references to `foo` damn!
// oh wait we have a backup \o/
that.hello(); // "world"
});
}
};
In the above code, we see that the value of this changed with the nested scope, but we wanted the value of this from the original scope. So we 'copied' this to that and used the copy instead of this. Clever, eh?
Index:
What is held in this by default?
What if we call the function as a method with Object-dot notation?
What if we use the new keyword?
How do we manipulate this with call and apply?
Using bind.
Copying this to solve nested-scope issues.
"this" is all about scope. Every function has its own scope, and since everything in JS is an object, even a function can store some values into itself using "this". OOP 101 teaches that "this" is only applicable to instances of an object. Therefore, every-time a function executes, a new "instance" of that function has a new meaning of "this".
Most people get confused when they try to use "this" inside of anonymous closure functions like:
(function(value) {
this.value = value;
$('.some-elements').each(function(elt){
elt.innerHTML = this.value; // uh oh!! possibly undefined
});
})(2);
So here, inside each(), "this" doesn't hold the "value" that you expect it to (from this.value = value; above it). So, to get over this (no pun intended) problem, a developer could:
(function(value) {
var self = this; // small change
self.value = value;
$('.some-elements').each(function(elt){
elt.innerHTML = self.value; // phew!! == 2
});
})(2);
Try it out; you'll begin to like this pattern of programming
Since this thread has bumped up, I have compiled few points for readers new to this topic.
How is the value of this determined?
We use this similar to the way we use pronouns in natural languages like English: “John is running fast because he is trying to catch the train.” Instead we could have written “… John is trying to catch the train”.
var person = {
firstName: "Penelope",
lastName: "Barrymore",
fullName: function () {
// We use "this" just as in the sentence above:
console.log(this.firstName + " " + this.lastName);
// We could have also written:
console.log(person.firstName + " " + person.lastName);
}
}
this is not assigned a value until an object invokes the function where it is defined. In the global scope, all global variables and functions are defined on the window object. Therefore, this in a global function refers to (and has the value of) the global window object.
When use strict, this in global and in anonymous functions that are not bound to any object holds a value of undefined.
The this keyword is most misunderstood when: 1) we borrow a method that uses this, 2) we assign a method that uses this to a variable, 3) a function that uses this is passed as a callback function, and 4) this is used inside a closure — an inner function. (2)
What holds the future
Defined in ECMA Script 6, arrow-functions adopt the this binding from the
enclosing (function or global) scope.
function foo() {
// return an arrow function
return (a) => {
// `this` here is lexically inherited from `foo()`
console.log(this.a);
};
}
var obj1 = { a: 2 };
var obj2 = { a: 3 };
var bar = foo.call(obj1);
bar.call( obj2 ); // 2, not 3!
While arrow-functions provide an alternative to using bind(), it’s important to note that they essentially are disabling the traditional this mechanism in favor of more widely understood lexical scoping. (1)
References:
this & Object Prototypes, by Kyle Simpson. © 2014 Getify Solutions.
javascriptissexy.com - http://goo.gl/pvl0GX
Angus Croll - http://goo.gl/Z2RacU
this in JavaScript always refers to the 'owner' of the function that is being executed.
If no explicit owner is defined, then the top most owner, the window object, is referenced.
So if I did
function someKindOfFunction() {
this.style = 'foo';
}
element.onclick = someKindOfFunction;
this would refer to the element object. But be careful, a lot of people make this mistake.
<element onclick="someKindOfFunction()">
In the latter case, you merely reference the function, not hand it over to the element. Therefore, this will refer to the window object.
Every execution context in javascript has a this parameter that is set by:
How the function is called (including as an object method, use of call and apply, use of new)
Use of bind
Lexically for arrow functions (they adopt the this of their outer execution context)
Whether the code is in strict or non-strict mode
Whether the code was invoked using eval
You can set the value of this using func.call, func.apply or func.bind.
By default, and what confuses most beginners, when a listener is called after an event is raised on a DOM element, the this value of the function is the DOM element.
jQuery makes this trivial to change with jQuery.proxy.
Daniel, awesome explanation! A couple of words on this and good list of this execution context pointer in case of event handlers.
In two words, this in JavaScript points the object from whom (or from whose execution context) the current function was run and it's always read-only, you can't set it anyway (such an attempt will end up with 'Invalid left-hand side in assignment' message.
For event handlers: inline event handlers, such as <element onclick="foo">, override any other handlers attached earlier and before, so be careful and it's better to stay off of inline event delegation at all.
And thanks to Zara Alaverdyan who inspired me to this list of examples through a dissenting debate :)
el.onclick = foo; // in the foo - obj
el.onclick = function () {this.style.color = '#fff';} // obj
el.onclick = function() {doSomething();} // In the doSomething -
Window
el.addEventListener('click',foo,false) // in the foo - obj
el.attachEvent('onclick, function () { // this }') // window, all the
compliance to IE :)
<button onclick="this.style.color = '#fff';"> // obj
<button onclick="foo"> // In the foo - window, but you can <button
onclick="foo(this)">
Here is one good source of this in JavaScript.
Here is the summary:
global this
In a browser, at the global scope, this is the windowobject
<script type="text/javascript">
console.log(this === window); // true
var foo = "bar";
console.log(this.foo); // "bar"
console.log(window.foo); // "bar"
In node using the repl, this is the top namespace. You can refer to it as global.
>this
{ ArrayBuffer: [Function: ArrayBuffer],
Int8Array: { [Function: Int8Array] BYTES_PER_ELEMENT: 1 },
Uint8Array: { [Function: Uint8Array] BYTES_PER_ELEMENT: 1 },
...
>global === this
true
In node executing from a script, this at the global scope starts as an empty object. It is not the same as global
\\test.js
console.log(this); \\ {}
console.log(this === global); \\ fasle
function this
Except in the case of DOM event handlers or when a thisArg is provided (see further down), both in node and in a browser using this in a function that is not called with new references the global scope…
<script type="text/javascript">
foo = "bar";
function testThis() {
this.foo = "foo";
}
console.log(this.foo); //logs "bar"
testThis();
console.log(this.foo); //logs "foo"
</script>
If you use use strict;, in which case this will be undefined
<script type="text/javascript">
foo = "bar";
function testThis() {
"use strict";
this.foo = "foo";
}
console.log(this.foo); //logs "bar"
testThis(); //Uncaught TypeError: Cannot set property 'foo' of undefined
</script>
If you call a function with new the this will be a new context, it will not reference the global this.
<script type="text/javascript">
foo = "bar";
function testThis() {
this.foo = "foo";
}
console.log(this.foo); //logs "bar"
new testThis();
console.log(this.foo); //logs "bar"
console.log(new testThis().foo); //logs "foo"
</script>
prototype this
Functions you create become function objects. They automatically get a special prototype property, which is something you can assign values to. When you create an instance by calling your function with new you get access to the values you assigned to the prototype property. You access those values using this.
function Thing() {
console.log(this.foo);
}
Thing.prototype.foo = "bar";
var thing = new Thing(); //logs "bar"
console.log(thing.foo); //logs "bar"
It is usually a mistake to assign arrays or objects on the prototype. If you want instances to each have their own arrays, create them in the function, not the prototype.
function Thing() {
this.things = [];
}
var thing1 = new Thing();
var thing2 = new Thing();
thing1.things.push("foo");
console.log(thing1.things); //logs ["foo"]
console.log(thing2.things); //logs []
object this
You can use this in any function on an object to refer to other properties on that object. This is not the same as an instance created with new.
var obj = {
foo: "bar",
logFoo: function () {
console.log(this.foo);
}
};
obj.logFoo(); //logs "bar"
DOM event this
In an HTML DOM event handler, this is always a reference to the DOM element the event was attached to
function Listener() {
document.getElementById("foo").addEventListener("click",
this.handleClick);
}
Listener.prototype.handleClick = function (event) {
console.log(this); //logs "<div id="foo"></div>"
}
var listener = new Listener();
document.getElementById("foo").click();
Unless you bind the context
function Listener() {
document.getElementById("foo").addEventListener("click",
this.handleClick.bind(this));
}
Listener.prototype.handleClick = function (event) {
console.log(this); //logs Listener {handleClick: function}
}
var listener = new Listener();
document.getElementById("foo").click();
HTML this
Inside HTML attributes in which you can put JavaScript, this is a reference to the element.
<div id="foo" onclick="console.log(this);"></div>
<script type="text/javascript">
document.getElementById("foo").click(); //logs <div id="foo"...
</script>
eval this
You can use eval to access this.
function Thing () {
}
Thing.prototype.foo = "bar";
Thing.prototype.logFoo = function () {
eval("console.log(this.foo)"); //logs "bar"
}
var thing = new Thing();
thing.logFoo();
with this
You can use with to add this to the current scope to read and write to values on this without referring to this explicitly.
function Thing () {
}
Thing.prototype.foo = "bar";
Thing.prototype.logFoo = function () {
with (this) {
console.log(foo);
foo = "foo";
}
}
var thing = new Thing();
thing.logFoo(); // logs "bar"
console.log(thing.foo); // logs "foo"
jQuery this
the jQuery will in many places have this refer to a DOM element.
<div class="foo bar1"></div>
<div class="foo bar2"></div>
<script type="text/javascript">
$(".foo").each(function () {
console.log(this); //logs <div class="foo...
});
$(".foo").on("click", function () {
console.log(this); //logs <div class="foo...
});
$(".foo").each(function () {
this.click();
});
</script>
There is a lot of confusion regarding how "this" keyword is interpreted in JavaScript. Hopefully this article will lay all those to rest once and for all. And a lot more. Please read the entire article carefully. Be forewarned that this article is long.
Irrespective of the context in which it is used, "this" always references the "current object" in Javascript. However, what the "current object" is differs according to context. The context may be exactly 1 of the 6 following:
Global (i.e. Outside all functions)
Inside Direct "Non Bound Function" Call (i.e. a function that has not been bound by calling functionName.bind)
Inside Indirect "Non Bound Function" Call through functionName.call and functionName.apply
Inside "Bound Function" Call (i.e. a function that has been bound by calling functionName.bind)
While Object Creation through "new"
Inside Inline DOM event handler
The following describes each of this contexts one by one:
Global Context (i.e. Outside all functions):
Outside all functions (i.e. in global context) the "current
object" (and hence the value of "this") is always the
"window" object for browsers.
Inside Direct "Non Bound Function" Call:
Inside a Direct "Non Bound Function" Call, the object that
invoked the function call becomes the "current object" (and hence
the value of "this"). If a function is called without a explicit current object, the current object is either the "window" object (For Non Strict Mode) or undefined (For Strict Mode) . Any function (or variable) defined in
Global Context automatically becomes a property of the "window" object.For e.g Suppose function is defined in Global Context as
function UserDefinedFunction(){
alert(this)
}
it becomes the property of the window object, as if you have defined
it as
window.UserDefinedFunction=function(){
alert(this)
}
In "Non Strict Mode", Calling/Invoking this function directly through "UserDefinedFunction()" will automatically call/invoke
it as "window.UserDefinedFunction()" making "window" as the
"current object" (and hence the value of "this") within "UserDefinedFunction".Invoking this function in "Non Strict Mode" will result in the following
UserDefinedFunction() // displays [object Window] as it automatically gets invoked as window.UserDefinedFunction()
In "Strict Mode", Calling/Invoking the function directly through
"UserDefinedFunction()" will "NOT" automatically call/invoke it as "window.UserDefinedFunction()".Hence the "current
object" (and the value of "this") within
"UserDefinedFunction" shall be undefined. Invoking this function in "Strict Mode" will result in the following
UserDefinedFunction() // displays undefined
However, invoking it explicitly using window object shall result in
the following
window.UserDefinedFunction() // "always displays [object Window] irrespective of mode."
Let us look at another example. Please look at the following code
function UserDefinedFunction()
{
alert(this.a + "," + this.b + "," + this.c + "," + this.d)
}
var o1={
a:1,
b:2,
f:UserDefinedFunction
}
var o2={
c:3,
d:4,
f:UserDefinedFunction
}
o1.f() // Shall display 1,2,undefined,undefined
o2.f() // Shall display undefined,undefined,3,4
In the above example we see that when "UserDefinedFunction" was
invoked through o1, "this" takes value of o1 and the
value of its properties "a" and "b" get displayed. The value
of "c" and "d" were shown as undefined as o1 does
not define these properties
Similarly when "UserDefinedFunction" was invoked through o2,
"this" takes value of o2 and the value of its properties "c" and "d" get displayed.The value of "a" and "b" were shown as undefined as o2 does not define these properties.
Inside Indirect "Non Bound Function" Call through functionName.call and functionName.apply:
When a "Non Bound Function" is called through
functionName.call or functionName.apply, the "current object" (and hence the value of "this") is set to the value of
"this" parameter (first parameter) passed to call/apply. The following code demonstrates the same.
function UserDefinedFunction()
{
alert(this.a + "," + this.b + "," + this.c + "," + this.d)
}
var o1={
a:1,
b:2,
f:UserDefinedFunction
}
var o2={
c:3,
d:4,
f:UserDefinedFunction
}
UserDefinedFunction.call(o1) // Shall display 1,2,undefined,undefined
UserDefinedFunction.apply(o1) // Shall display 1,2,undefined,undefined
UserDefinedFunction.call(o2) // Shall display undefined,undefined,3,4
UserDefinedFunction.apply(o2) // Shall display undefined,undefined,3,4
o1.f.call(o2) // Shall display undefined,undefined,3,4
o1.f.apply(o2) // Shall display undefined,undefined,3,4
o2.f.call(o1) // Shall display 1,2,undefined,undefined
o2.f.apply(o1) // Shall display 1,2,undefined,undefined
The above code clearly shows that the "this" value for any "NON
Bound Function" can be altered through call/apply. Also,if the
"this" parameter is not explicitly passed to call/apply, "current object" (and hence the value of "this") is set to "window" in Non strict mode and "undefined" in strict mode.
Inside "Bound Function" Call (i.e. a function that has been bound by calling functionName.bind):
A bound function is a function whose "this" value has been
fixed. The following code demonstrated how "this" works in case
of bound function
function UserDefinedFunction()
{
alert(this.a + "," + this.b + "," + this.c + "," + this.d)
}
var o1={
a:1,
b:2,
f:UserDefinedFunction,
bf:null
}
var o2={
c:3,
d:4,
f:UserDefinedFunction,
bf:null
}
var bound1=UserDefinedFunction.bind(o1); // permanantly fixes "this" value of function "bound1" to Object o1
bound1() // Shall display 1,2,undefined,undefined
var bound2=UserDefinedFunction.bind(o2); // permanantly fixes "this" value of function "bound2" to Object o2
bound2() // Shall display undefined,undefined,3,4
var bound3=o1.f.bind(o2); // permanantly fixes "this" value of function "bound3" to Object o2
bound3() // Shall display undefined,undefined,3,4
var bound4=o2.f.bind(o1); // permanantly fixes "this" value of function "bound4" to Object o1
bound4() // Shall display 1,2,undefined,undefined
o1.bf=UserDefinedFunction.bind(o2) // permanantly fixes "this" value of function "o1.bf" to Object o2
o1.bf() // Shall display undefined,undefined,3,4
o2.bf=UserDefinedFunction.bind(o1) // permanantly fixes "this" value of function "o2.bf" to Object o1
o2.bf() // Shall display 1,2,undefined,undefined
bound1.call(o2) // Shall still display 1,2,undefined,undefined. "call" cannot alter the value of "this" for bound function
bound1.apply(o2) // Shall still display 1,2,undefined,undefined. "apply" cannot alter the value of "this" for bound function
o2.bf.call(o2) // Shall still display 1,2,undefined,undefined. "call" cannot alter the value of "this" for bound function
o2.bf.apply(o2) // Shall still display 1,2,undefined,undefined."apply" cannot alter the value of "this" for bound function
As given in the code above, "this" value for any "Bound Function"
CANNOT be altered through call/apply. Also, if the "this"
parameter is not explicitly passed to bind, "current object"
(and hence the value of "this" ) is set to "window" in Non
strict mode and "undefined" in strict mode. One more thing.
Binding an already bound function does not change the value of "this".
It remains set as the value set by first bind function.
While Object Creation through "new":
Inside a constructor function, the "current object" (and hence the value of
"this") references the object that is currently being created
through "new" irrespective of the bind status of the function. However
if the constructor is a bound function it shall get called with
predefined set of arguments as set for the bound function.
Inside Inline DOM event handler:
Please look at the following HTML Snippet
<button onclick='this.style.color=white'>Hello World</button>
<div style='width:100px;height:100px;' onclick='OnDivClick(event,this)'>Hello World</div>
The "this" in above examples refer to "button" element and the
"div" element respectively.
In the first example, the font color of the button shall be set to
white when it is clicked.
In the second example when the "div" element is clicked it shall
call the OnDivClick function with its second parameter
referencing the clicked div element. However the value of "this"
within OnDivClick SHALL NOT reference the clicked div
element. It shall be set as the "window object" or
"undefined" in Non strict and Strict Modes respectively (if OnDivClick is an unbound function) or set to a predefined
Bound value (if OnDivClick is a bound function)
The following summarizes the entire article
In Global Context "this" always refers to the "window" object
Whenever a function is invoked, it is invoked in context of an
object ("current object"). If the current object is not explicitly provided,
the current object is the "window object" in NON Strict
Mode and "undefined" in Strict Mode by default.
The value of "this" within a Non Bound function is the reference to object in context of which the function is invoked ("current object")
The value of "this" within a Non Bound function can be overriden by
call and apply methods of the function.
The value of "this" is fixed for a Bound function and cannot be
overriden by call and apply methods of the function.
Binding and already bound function does not change the value of "this". It remains set as the value set by first bind function.
The value of "this" within a constructor is the object that is being
created and initialized
The value of "this" within an inline DOM event handler is reference
to the element for which the event handler is given.
Probably the most detailed and comprehensive article on this is the following:
Gentle explanation of 'this' keyword in JavaScript
The idea behind this is to understand that the function invocation types have the significant importance on setting this value.
When having troubles identifying this, do not ask yourself:
Where is this taken from?
but do ask yourself:
How is the function invoked?
For an arrow function (special case of context transparency) ask yourself:
What value has this where the arrow function is defined?
This mindset is correct when dealing with this and will save you from headache.
This is the best explanation I've seen: Understand JavaScripts this with Clarity
The this reference ALWAYS refers to (and holds the value of) an
object—a singular object—and it is usually used inside a function or a
method, although it can be used outside a function in the global
scope. Note that when we use strict mode, this holds the value of
undefined in global functions and in anonymous functions that are not
bound to any object.
There are Four Scenarios where this can be confusing:
When we pass a method (that uses this) as an argument to be used as a callback function.
When we use an inner function (a closure). It is important to take note that closures cannot access the outer function’s this variable by using the this keyword because the this variable is accessible only by the function itself, not by inner functions.
When a method which relies on this is assigned to a variable across contexts, in which case this references another object than originally intended.
When using this along with the bind, apply, and call methods.
He gives code examples, explanations, and solutions, which I thought was very helpful.
this is one of the misunderstood concept in JavaScript because it behaves little differently from place to place. Simply, this refers to the "owner" of the function we are currently executing.
this helps to get the current object (a.k.a. execution context) we work with. If you understand in which object the current function is getting executed, you can understand easily what current this is
var val = "window.val"
var obj = {
val: "obj.val",
innerMethod: function () {
var val = "obj.val.inner",
func = function () {
var self = this;
return self.val;
};
return func;
},
outerMethod: function(){
return this.val;
}
};
//This actually gets executed inside window object
console.log(obj.innerMethod()()); //returns window.val
//Breakdown in to 2 lines explains this in detail
var _inn = obj.innerMethod();
console.log(_inn()); //returns window.val
console.log(obj.outerMethod()); //returns obj.val
Above we create 3 variables with same name 'val'. One in global context, one inside obj and the other inside innerMethod of obj. JavaScript resolves identifiers within a particular context by going up the scope chain from local go global.
Few places where this can be differentiated
Calling a method of a object
var status = 1;
var helper = {
status : 2,
getStatus: function () {
return this.status;
}
};
var theStatus1 = helper.getStatus(); //line1
console.log(theStatus1); //2
var theStatus2 = helper.getStatus;
console.log(theStatus2()); //1
When line1 is executed, JavaScript establishes an execution context (EC) for the function call, setting this to the object referenced by whatever came before the last ".". so in the last line you can understand that a() was executed in the global context which is the window.
With Constructor
this can be used to refer to the object being created
function Person(name){
this.personName = name;
this.sayHello = function(){
return "Hello " + this.personName;
}
}
var person1 = new Person('Scott');
console.log(person1.sayHello()); //Hello Scott
var person2 = new Person('Hugh');
var sayHelloP2 = person2.sayHello;
console.log(sayHelloP2()); //Hello undefined
When new Person() is executed, a completely new object is created. Person is called and its this is set to reference that new object.
Function call
function testFunc() {
this.name = "Name";
this.myCustomAttribute = "Custom Attribute";
return this;
}
var whatIsThis = testFunc();
console.log(whatIsThis); //window
var whatIsThis2 = new testFunc();
console.log(whatIsThis2); //testFunc() / object
console.log(window.myCustomAttribute); //Custom Attribute
If we miss new keyword, whatIsThis referes to the most global context it can find(window)
With event handlers
If the event handler is inline, this refers to global object
<script type="application/javascript">
function click_handler() {
alert(this); // alerts the window object
}
</script>
<button id='thebutton' onclick='click_handler()'>Click me!</button>
When adding event handler through JavaScript, this refers to DOM element that generated the event.
You can also manipulate the context using .apply() .call() and .bind()
JQuery proxy is another way you can use to make sure this in a function will be the value you desire. (Check Understanding $.proxy(), jQuery.proxy() usage)
What does var that = this means in JavaScript
The value of "this" depends on the "context" in which the function is executed. The context can be any object or the global object, i.e., window.
So the Semantic of "this" is different from the traditional OOP languages. And it causes problems:
1. when a function is passed to another variable (most likely, a callback); and 2. when a closure is invoked from a member method of a class.
In both cases, this is set to window.
In pseudoclassical terms, the way many lectures teach the 'this' keyword is as an object instantiated by a class or object constructor. Each time a new object is constructed from a class, imagine that under the hood a local instance of a 'this' object is created and returned. I remember it taught like this:
function Car(make, model, year) {
var this = {}; // under the hood, so to speak
this.make = make;
this.model = model;
this.year = year;
return this; // under the hood
}
var mycar = new Car('Eagle', 'Talon TSi', 1993);
// ========= under the hood
var this = {};
this.make = 'Eagle';
this.model = 'Talon TSi';
this.year = 1993;
return this;
Whould this help? (Most confusion of 'this' in javascript is coming from the fact that it generally is not linked to your object, but to the current executing scope -- that might not be exactly how it works but is always feels like that to me -- see the article for a complete explanation)
A little bit info about this keyword
Let's log this keyword to the console in global scope without any more code but
console.log(this)
In Client/Browser this keyword is a global object which is window
console.log(this === window) // true
and
In Server/Node/Javascript runtime this keyword is also a global object which is module.exports
console.log(this === module.exports) // true
console.log(this === exports) // true
Keep in mind exports is just a reference to module.exports
I have a different take on this from the other answers that I hope is helpful.
One way to look at JavaScript is to see that there are only 1 way to call a function1. It is
functionObject.call(objectForThis, arg0, arg1, arg2, ...);
There is always some value supplied for objectForThis.
Everything else is syntactic sugar for functionObject.call
So, everything else can be described by how it translates into functionObject.call.
If you just call a function then this is the "global object" which in the browser is the window
function foo() {
console.log(this);
}
foo(); // this is the window object
In other words,
foo();
was effectively translated into
foo.call(window);
Note that if you use strict mode then this will be undefined
'use strict';
function foo() {
console.log(this);
}
foo(); // this is the window object
which means
In other words,
foo();
was effectively translated into
foo.call(undefined);
In JavaScript there are operators like + and - and *. There is also the dot operator which is .
The . operator when used with a function on the right and an object on the left effectively means "pass object as this to function.
Example
const bar = {
name: 'bar',
foo() {
console.log(this);
},
};
bar.foo(); // this is bar
In other words bar.foo() translates into const temp = bar.foo; temp.call(bar);
Note that it doesn't matter how the function was created (mostly...). All of these will produce the same results
const bar = {
name: 'bar',
fn1() { console.log(this); },
fn2: function() { console.log(this); },
fn3: otherFunction,
};
function otherFunction() { console.log(this) };
bar.fn1(); // this is bar
bar.fn2(); // this is bar
bar.fn3(); // this is bar
Again these all are just syntactic sugar for
{ const temp = bar.fn1; temp.call(bar); }
{ const temp = bar.fn2; temp.call(bar); }
{ const temp = bar.fn3; temp.call(bar); }
One other wrinkle is the prototype chain. When you use a.b JavaScript first looks on the object referenced directly by a for the property b. If b is not found on the object then JavaScript will look in the object's prototype to find b.
There are various ways to define an object's prototype, the most common in 2019 is the class keyword. For the purposes of this though it doesn't matter. What matters is that as it looks in object a for property b if it finds property b on the object or in it's prototype chain if b ends up being a function then the same rules as above apply. The function b references will be called using the call method and passing a as objectForThis as shown a the top of this answer.
Now. Let's imagine we make a function that explicitly sets this before calling another function and then call it with the . (dot) operator
function foo() {
console.log(this);
}
function bar() {
const objectForThis = {name: 'moo'}
foo.call(objectForThis); // explicitly passing objectForThis
}
const obj = {
bar,
};
obj.bar();
Following the translation to use call, obj.bar() becomes const temp = obj.bar; temp.call(obj);. When we enter the bar function we call foo but we explicitly passed in another object for objectForThis so when we arrive at foo this is that inner object.
This is what both bind and => functions effectively do. They are more syntactic sugar. They effectively build a new invisible function exactly like bar above that explicitly sets this before it calls whatever function is specified. In the case of bind this is set to whatever you pass to bind.
function foo() {
console.log(this);
}
const bar = foo.bind({name: 'moo'});
// bind created a new invisible function that calls foo with the bound object.
bar();
// the objectForThis we are passing to bar here is ignored because
// the invisible function that bind created will call foo with with
// the object we bound above
bar.call({name: 'other'});
Note that if functionObject.bind did not exist we could make our own like this
function bind(fn, objectForThis) {
return function(...args) {
return fn.call(objectForthis, ...args);
};
}
and then we could call it like this
function foo() {
console.log(this);
}
const bar = bind(foo, {name:'abc'});
Arrow functions, the => operator are syntactic sugar for bind
const a = () => {console.log(this)};
is the same as
const tempFn = function() {console.log(this)};
const a = tempFn.bind(this);
Just like bind, a new invisible function is created that calls the given function with a bound value for objectForThis but unlike bind the object to be bound is implicit. It's whatever this happens to be when the => operator is used.
So, just like the rules above
const a = () => { console.log(this); } // this is the global object
'use strict';
const a = () => { console.log(this); } // this is undefined
function foo() {
return () => { console.log(this); }
}
const obj = {
foo,
};
const b = obj.foo();
b();
obj.foo() translates to const temp = obj.foo; temp.call(obj); which means the arrow operator inside foo will bind obj to a new invisible function and return that new invisible function which is assigned to b. b() will work as it always has as b.call(window) or b.call(undefined) calling the new invisible function that foo created. That invisible function ignores the this passed into it and passes obj as objectForThis` to the arrow function.
The code above translates to
function foo() {
function tempFn() {
console.log(this);
}
return tempFn.bind(this);
}
const obj = {
foo,
};
const b = obj.foo();
b.call(window or undefined if strict mode);
1apply is another function similar to call
functionName.apply(objectForThis, arrayOfArgs);
But as of ES6 conceptually you can even translate that into
functionName.call(objectForThis, ...arrayOfArgs);
"this" in JavaScript
this is one of the properties of the Execution Context.
this property is created every time a function is executed and not
before that.
Its value is not static but rather depends on how it is being used.
takes a value that points to the owner of the function in which it is
used
There are different ways in which the "this" keyword can be used, below are the example for it (method, regular function, arrow function, Event listener, Explicit function Binding).
1. Inside a method.
this === (to the object that is calling the Method).
In the above example the method " fullName()" is called by an Object "person" hence the value of this inside the method " fullName()" will be equal to the "person" Object.
2. Inside a Function.
i) function declaration/expression
in loose mode this === window (object)
in Strict mode this === undefined
Note : this property works the same while defining a function using function declaration or function expression approach.
ii) Arrow Function :
Arrow Function does not have their own this property, they take the value of this as their surrounding Function.
If the surrounding function is not present i.e if they are defined at the global level then this === window (object)
3. Event Listener
this === object on which the handler is attached.
click event bind to the Document object
In the above example since the click handler is attached to the "document" object, this will be equal to the "document" object
4. Explicit Function Binding (call, Apply, Bind)
The call() and apply() methods are predefined JavaScript methods.
They can both be used to call an object method with another object as an argument.
In the above example this inside the "printFullDetails()" is explicitly set to the personObj1 and personObj2 by passing as the first argument to call method.
You can Explore more about call, apply and bind methods here.
this use for Scope just like this
<script type="text/javascript" language="javascript">
$('#tbleName tbody tr').each(function{
var txt='';
txt += $(this).find("td").eq(0).text();
\\same as above but synatx different
var txt1='';
txt1+=$('#tbleName tbody tr').eq(0).text();
alert(txt1)
});
</script>
value of txt1 and txt is same
in Above example
$(this)=$('#tbleName tbody tr') is Same
Summary this Javascript:
The value of this is determined by how the function is invoked not, where it was created!
Usually the value of this is determined by the Object which is left of the dot. (window in global space)
In event listeners the value of this refers to the DOM element on which the event was called.
When in function is called with the new keyword the value of this refers to the newly created object
You can manipulate the value of this with the functions: call, apply, bind
Example:
let object = {
prop1: function () {console.log(this);}
}
object.prop1(); // object is left of the dot, thus this is object
const myFunction = object.prop1 // We store the function in the variable myFunction
myFunction(); // Here we are in the global space
// myFunction is a property on the global object
// Therefore it logs the window object
Example event listeners:
document.querySelector('.foo').addEventListener('click', function () {
console.log(this); // This refers to the DOM element the eventListener was invoked from
})
document.querySelector('.foo').addEventListener('click', () => {
console.log(this); // Tip, es6 arrow function don't have their own binding to the this v
}) // Therefore this will log the global object
.foo:hover {
color: red;
cursor: pointer;
}
<div class="foo">click me</div>
Example constructor:
function Person (name) {
this.name = name;
}
const me = new Person('Willem');
// When using the new keyword the this in the constructor function will refer to the newly created object
console.log(me.name);
// Therefore, the name property was placed on the object created with new keyword.
To understand "this" properly one must understand the context and scope and difference between them.
Scope: In javascript scope is related to the visibility of the variables, scope achieves through the use of the function. (Read more about scope)
Context: Context is related to objects. It refers to the object to which a function belongs. When you use the JavaScript “this” keyword, it refers to the object to which function belongs. For example, inside of a function, when you say: “this.accoutNumber”, you are referring to the property “accoutNumber”, that belongs to the object to which that function belongs.
If the object “myObj” has a method called “getMyName”, when the JavaScript keyword “this” is used inside of “getMyName”, it refers to “myObj”. If the function “getMyName” were executed in the global scope, then “this” refers to the window object (except in strict mode).
Now let's see some example:
<script>
console.log('What is this: '+this);
console.log(this);
</script>
Runnig abobve code in browser output will:
According to the output you are inside of the context of the window object, it is also visible that window prototype refers to the Object.
Now let's try inside of a function:
<script>
function myFunc(){
console.log('What is this: '+this);
console.log(this);
}
myFunc();
</script>
Output:
The output is the same because we logged 'this' variable in the global scope and we logged it in functional scope, we didn't change the context. In both case context was same, related to widow object.
Now let's create our own object. In javascript, you can create an object in many ways.
<script>
var firstName = "Nora";
var lastName = "Zaman";
var myObj = {
firstName:"Lord",
lastName:'Baron',
printNameGetContext:function(){
console.log(firstName + " "+lastName);
console.log(this.firstName +" "+this.lastName);
return this;
}
}
var context = myObj.printNameGetContext();
console.log(context);
</script>
Output:
So from the above example, we found that 'this' keyword is referring to a new context that is related to myObj, and myObject also has prototype chain to Object.
Let's go throw another example:
<body>
<button class="btn">Click Me</button>
<script>
function printMe(){
//Terminal2: this function declared inside window context so this function belongs to the window object.
console.log(this);
}
document.querySelector('.btn').addEventListener('click', function(){
//Terminal1: button context, this callback function belongs to DOM element
console.log(this);
printMe();
})
</script>
</body>
output:
Make sense right? (read comments)
If you having trouble to understand the above example let's try with our own callback;
<script>
var myObj = {
firstName:"Lord",
lastName:'Baron',
printName:function(callback1, callback2){
//Attaching callback1 with this myObj context
this.callback1 = callback1;
this.callback1(this.firstName +" "+this.lastName)
//We did not attached callback2 with myObj so, it's reamin with window context by default
callback2();
/*
//test bellow codes
this.callback2 = callback2;
this.callback2();
*/
}
}
var callback2 = function (){
console.log(this);
}
myObj.printName(function(data){
console.log(data);
console.log(this);
}, callback2);
</script>
output:
Now let's Understand Scope, Self, IIFE and THIS how behaves
var color = 'red'; // property of window
var obj = {
color:'blue', // property of window
printColor: function(){ // property of obj, attached with obj
var self = this;
console.log('In printColor -- this.color: '+this.color);
console.log('In printColor -- self.color: '+self.color);
(function(){ // decleard inside of printColor but not property of object, it will executed on window context.
console.log(this)
console.log('In IIFE -- this.color: '+this.color);
console.log('In IIFE -- self.color: '+self.color);
})();
function nestedFunc(){// decleard inside of printColor but not property of object, it will executed on window context.
console.log('nested fun -- this.color: '+this.color);
console.log('nested fun -- self.color: '+self.color);
}
nestedFunc(); // executed on window context
return nestedFunc;
}
};
obj.printColor()(); // returned function executed on window context
</script>
Output is pretty awesome right?
I am looking to find a clear explanation of what the "this" keyword does, and how to use it correctly.
It seems to behave strangely, and I don't fully understand why.
How does this work and when should it be used?
this is a keyword in JavaScript that is a property of an execution context. Its main use is in functions and constructors.
The rules for this are quite simple (if you stick to best practices).
Technical description of this in the specification
The ECMAScript standard defines this via the abstract operation (abbreviated AO) ResolveThisBinding:
The [AO] ResolveThisBinding […] determines the binding of the keyword this using the LexicalEnvironment of the running execution context. [Steps]:
Let envRec be GetThisEnvironment().
Return ? envRec.GetThisBinding().
Global Environment Records, module Environment Records, and function Environment Records each have their own GetThisBinding method.
The GetThisEnvironment AO finds the current running execution context’s LexicalEnvironment and finds the closest ascendant Environment Record (by iteratively accessing their [[OuterEnv]] properties) which has a this binding (i.e. HasThisBinding returns true). This process ends in one of the three Environment Record types.
The value of this often depends on whether code is in strict mode.
The return value of GetThisBinding reflects the value of this of the current execution context, so whenever a new execution context is established, this resolves to a distinct value. This can also happen when the current execution context is modified. The following subsections list the five cases where this can happen.
You can put the code samples in the AST explorer to follow along with specification details.
1. Global execution context in scripts
This is script code evaluated at the top level, e.g. directly inside a <script>:
<script>
// Global context
console.log(this); // Logs global object.
setTimeout(function(){
console.log("Not global context");
});
</script>
When in the initial global execution context of a script, evaluating this causes GetThisBinding to take the following steps:
The GetThisBinding concrete method of a global Environment Record envRec […] [does this]:
Return envRec.[[GlobalThisValue]].
The [[GlobalThisValue]] property of a global Environment Record is always set to the host-defined global object, which is reachable via globalThis (window on Web, global on Node.js; Docs on MDN). Follow the steps of InitializeHostDefinedRealm to learn how the [[GlobalThisValue]] property comes to be.
2. Global execution context in modules
Modules have been introduced in ECMAScript 2015.
This applies to modules, e.g. when directly inside a <script type="module">, as opposed to a simple <script>.
When in the initial global execution context of a module, evaluating this causes GetThisBinding to take the following steps:
The GetThisBinding concrete method of a module Environment Record […] [does this]:
Return undefined.
In modules, the value of this is always undefined in the global context. Modules are implicitly in strict mode.
3. Entering eval code
There are two kinds of eval calls: direct and indirect. This distinction exists since the ECMAScript 5th edition.
A direct eval call usually looks like eval(…); or (eval)(…); (or ((eval))(…);, etc.).1 It’s only direct if the call expression fits a narrow pattern.2
An indirect eval call involves calling the function reference eval in any other way. It could be eval?.(…), (…, eval)(…), window.eval(…), eval.call(…,…), etc. Given const aliasEval1 = eval; window.aliasEval2 = eval;, it would also be aliasEval1(…), aliasEval2(…). Separately, given const originalEval = eval; window.eval = (x) => originalEval(x);, calling eval(…) would also be indirect.
See chuckj’s answer to “(1, eval)('this') vs eval('this') in JavaScript?” and Dmitry Soshnikov’s ECMA-262-5 in detail – Chapter 2: Strict Mode (archived) for when you might use an indirect eval() call.
PerformEval executes the eval code. It creates a new declarative Environment Record as its LexicalEnvironment, which is where GetThisEnvironment gets the this value from.
Then, if this appears in eval code, the GetThisBinding method of the Environment Record found by GetThisEnvironment is called and its value returned.
And the created declarative Environment Record depends on whether the eval call was direct or indirect:
In a direct eval, it will be based on the current running execution context’s LexicalEnvironment.
In an indirect eval, it will be based on the [[GlobalEnv]] property (a global Environment Record) of the Realm Record which executed the indirect eval.
Which means:
In a direct eval, the this value doesn’t change; it’s taken from the lexical scope that called eval.
In an indirect eval, the this value is the global object (globalThis).
What about new Function? — new Function is similar to eval, but it doesn’t call the code immediately; it creates a function. A this binding doesn’t apply anywhere here, except when the function is called, which works normally, as explained in the next subsection.
4. Entering function code
Entering function code occurs when calling a function.
There are four categories of syntax to invoke a function.
The EvaluateCall AO is performed for these three:3
Normal function calls
Optional chaining calls
Tagged templates
And EvaluateNew is performed for this one:3
Constructor invocations
The actual function call happens at the Call AO, which is called with a thisValue determined from context; this argument is passed along in a long chain of call-related calls. Call calls the [[Call]] internal slot of the function. This calls PrepareForOrdinaryCall where a new function Environment Record is created:
A function Environment Record is a declarative Environment Record that is used to represent the top-level scope of a function and, if the function is not an ArrowFunction, provides a this binding. If a function is not an ArrowFunction function and references super, its function Environment Record also contains the state that is used to perform super method invocations from within the function.
In addition, there is the [[ThisValue]] field in a function Environment Record:
This is the this value used for this invocation of the function.
The NewFunctionEnvironment call also sets the function environment’s [[ThisBindingStatus]] property.
[[Call]] also calls OrdinaryCallBindThis, where the appropriate thisArgument is determined based on:
the original reference,
the kind of the function, and
whether or not the code is in strict mode.
Once determined, a final call to the BindThisValue method of the newly created function Environment Record actually sets the [[ThisValue]] field to the thisArgument.
Finally, this very field is where a function Environment Record’s GetThisBinding AO gets the value for this from:
The GetThisBinding concrete method of a function Environment Record envRec […] [does this]:
[…]
3. Return envRec.[[ThisValue]].
Again, how exactly the this value is determined depends on many factors; this was just a general overview. With this technical background, let’s examine all the concrete examples.
Arrow functions
When an arrow function is evaluated, the [[ThisMode]] internal slot of the function object is set to “lexical” in OrdinaryFunctionCreate.
At OrdinaryCallBindThis, which takes a function F:
Let thisMode be F.[[ThisMode]].
If thisMode is lexical, return NormalCompletion(undefined).
[…]
which just means that the rest of the algorithm which binds this is skipped. An arrow function does not bind its own this value.
So, what is this inside an arrow function, then? Looking back at ResolveThisBinding and GetThisEnvironment, the HasThisBinding method explicitly returns false.
The HasThisBinding concrete method of a function Environment Record envRec […] [does this]:
If envRec.[[ThisBindingStatus]] is lexical, return false; otherwise, return true.
So the outer environment is looked up instead, iteratively. The process will end in one of the three environments that have a this binding.
This just means that, in arrow function bodies, this comes from the lexical scope of the arrow function, or in other words (from Arrow function vs function declaration / expressions: Are they equivalent / exchangeable?):
Arrow functions don’t have their own this […] binding. Instead, [this identifier is] resolved in the lexical scope like any other variable. That means that inside an arrow function, this [refers] to the [value of this] in the environment the arrow function is defined in (i.e. “outside” the arrow function).
Function properties
In normal functions (function, methods), this is determined by how the function is called.
This is where these “syntax variants” come in handy.
Consider this object containing a function:
const refObj = {
func: function(){
console.log(this);
}
};
Alternatively:
const refObj = {
func(){
console.log(this);
}
};
In any of the following function calls, the this value inside func will be refObj.1
refObj.func()
refObj["func"]()
refObj?.func()
refObj.func?.()
refObj.func``
If the called function is syntactically a property of a base object, then this base will be the “reference” of the call, which, in usual cases, will be the value of this. This is explained by the evaluation steps linked above; for example, in refObj.func() (or refObj["func"]()), the CallMemberExpression is the entire expression refObj.func(), which consists of the MemberExpression refObj.func and the Arguments ().
But also, refObj.func and refObj play three roles, each:
they’re both expressions,
they’re both references, and
they’re both values.
refObj.func as a value is the callable function object; the corresponding reference is used to determine the this binding.
The optional chaining and tagged template examples work very similarly: basically, the reference is everything before the ?.(), before the ``, or before the ().
EvaluateCall uses IsPropertyReference of that reference to determine if it is a property of an object, syntactically. It’s trying to get the [[Base]] property of the reference (which is e.g. refObj, when applied to refObj.func; or foo.bar when applied to foo.bar.baz). If it is written as a property, then GetThisValue will get this [[Base]] property and use it as the this value.
Note: Getters / Setters work the same way as methods, regarding this. Simple properties don’t affect the execution context, e.g. here, this is in global scope:
const o = {
a: 1,
b: this.a, // Is `globalThis.a`.
[this.a]: 2 // Refers to `globalThis.a`.
};
Calls without base reference, strict mode, and with
A call without a base reference is usually a function that isn’t called as a property. For example:
func(); // As opposed to `refObj.func();`.
This also happens when passing or assigning methods, or using the comma operator. This is where the difference between Reference Record and Value is relevant.
Note function j: following the specification, you will notice that j can only return the function object (Value) itself, but not a Reference Record. Therefore the base reference refObj is lost.
const g = (f) => f(); // No base ref.
const h = refObj.func;
const j = () => refObj.func;
g(refObj.func);
h(); // No base ref.
j()(); // No base ref.
(0, refObj.func)(); // Another common pattern to remove the base ref.
EvaluateCall calls Call with a thisValue of undefined here. This makes a difference in OrdinaryCallBindThis (F: the function object; thisArgument: the thisValue passed to Call):
Let thisMode be F.[[ThisMode]].
[…]
If thisMode is strict, let thisValue be thisArgument.
Else,
If thisArgument is undefined or null, then
Let globalEnv be calleeRealm.[[GlobalEnv]].
[…]
Let thisValue be globalEnv.[[GlobalThisValue]].
Else,
Let thisValue be ! ToObject(thisArgument).
NOTE: ToObject produces wrapper objects […].
[…]
Note: step 5 sets the actual value of this to the supplied thisArgument in strict mode — undefined in this case. In “sloppy mode”, an undefined or null thisArgument results in this being the global this value.
If IsPropertyReference returns false, then EvaluateCall takes these steps:
Let refEnv be ref.[[Base]].
Assert: refEnv is an Environment Record.
Let thisValue be refEnv.WithBaseObject().
This is where an undefined thisValue may come from: refEnv.WithBaseObject() is always undefined, except in with statements. In this case, thisValue will be the binding object.
There’s also Symbol.unscopables (Docs on MDN) to control the with binding behavior.
To summarize, so far:
function f1(){
console.log(this);
}
function f2(){
console.log(this);
}
function f3(){
console.log(this);
}
const o = {
f1,
f2,
[Symbol.unscopables]: {
f2: true
}
};
f1(); // Logs `globalThis`.
with(o){
f1(); // Logs `o`.
f2(); // `f2` is unscopable, so this logs `globalThis`.
f3(); // `f3` is not on `o`, so this logs `globalThis`.
}
and:
"use strict";
function f(){
console.log(this);
}
f(); // Logs `undefined`.
// `with` statements are not allowed in strict-mode code.
Note that when evaluating this, it doesn’t matter where a normal function is defined.
.call, .apply, .bind, thisArg, and primitives
Another consequence of step 5 of OrdinaryCallBindThis, in conjunction with step 6.2 (6.b in the spec), is that a primitive this value is coerced to an object only in “sloppy” mode.
To examine this, let’s introduce another source for the this value: the three methods that override the this binding:4
Function.prototype.apply(thisArg, argArray)
Function.prototype. {call, bind} (thisArg, ...args)
.bind creates a bound function, whose this binding is set to thisArg and cannot change again. .call and .apply call the function immediately, with the this binding set to thisArg.
.call and .apply map directly to Call, using the specified thisArg. .bind creates a bound function with BoundFunctionCreate. These have their own [[Call]] method which looks up the function object’s [[BoundThis]] internal slot.
Examples of setting a custom this value:
function f(){
console.log(this);
}
const myObj = {},
g = f.bind(myObj),
h = (m) => m();
// All of these log `myObj`.
g();
f.bind(myObj)();
f.call(myObj);
h(g);
For objects, this is the same in strict and non-strict mode.
Now, try to supply a primitive value:
function f(){
console.log(this);
}
const myString = "s",
g = f.bind(myString);
g(); // Logs `String { "s" }`.
f.call(myString); // Logs `String { "s" }`.
In non-strict mode, primitives are coerced to their object-wrapped form. It’s the same kind of object you get when calling Object("s") or new String("s"). In strict mode, you can use primitives:
"use strict";
function f(){
console.log(this);
}
const myString = "s",
g = f.bind(myString);
g(); // Logs `"s"`.
f.call(myString); // Logs `"s"`.
Libraries make use of these methods, e.g. jQuery sets the this to the DOM element selected here:
$("button").click(function(){
console.log(this); // Logs the clicked button.
});
Constructors, classes, and new
When calling a function as a constructor using the new operator, EvaluateNew calls Construct, which calls the [[Construct]] method. If the function is a base constructor (i.e. not a class extends…{…}), it sets thisArgument to a new object created from the constructor’s prototype. Properties set on this in the constructor will end up on the resulting instance object. this is implicitly returned, unless you explicitly return your own non-primitive value.
A class is a new way of creating constructor functions, introduced in ECMAScript 2015.
function Old(a){
this.p = a;
}
const o = new Old(1);
console.log(o); // Logs `Old { p: 1 }`.
class New{
constructor(a){
this.p = a;
}
}
const n = new New(1);
console.log(n); // Logs `New { p: 1 }`.
Class definitions are implicitly in strict mode:
class A{
m1(){
return this;
}
m2(){
const m1 = this.m1;
console.log(m1());
}
}
new A().m2(); // Logs `undefined`.
super
The exception to the behavior with new is class extends…{…}, as mentioned above. Derived classes do not immediately set their this value upon invocation; they only do so once the base class is reached through a series of super calls (happens implicitly without an own constructor). Using this before calling super is not allowed.
Calling super calls the super constructor with the this value of the lexical scope (the function Environment Record) of the call. GetThisValue has a special rule for super calls. It uses BindThisValue to set this to that Environment Record.
class DerivedNew extends New{
constructor(a, a2){
// Using `this` before `super` results in a ReferenceError.
super(a);
this.p2 = a2;
}
}
const n2 = new DerivedNew(1, 2);
console.log(n2); // Logs `DerivedNew { p: 1, p2: 2 }`.
5. Evaluating class fields
Instance fields and static fields were introduced in ECMAScript 2022.
When a class is evaluated, ClassDefinitionEvaluation is performed, modifying the running execution context. For each ClassElement:
if a field is static, then this refers to the class itself,
if a field is not static, then this refers to the instance.
Private fields (e.g. #x) and methods are added to a PrivateEnvironment.
Static blocks are currently a TC39 stage 3 proposal. Static blocks work the same as static fields and methods: this inside them refers to the class itself.
Note that in methods and getters / setters, this works just like in normal function properties.
class Demo{
a = this;
b(){
return this;
}
static c = this;
static d(){
return this;
}
// Getters, setters, private modifiers are also possible.
}
const demo = new Demo;
console.log(demo.a, demo.b()); // Both log `demo`.
console.log(Demo.c, Demo.d()); // Both log `Demo`.
1: (o.f)() is equivalent to o.f(); (f)() is equivalent to f(). This is explained in this 2ality article (archived). Particularly see how a ParenthesizedExpression is evaluated.
2: It must be a MemberExpression, must not be a property, must have a [[ReferencedName]] of exactly "eval", and must be the %eval% intrinsic object.
3: Whenever the specification says “Let ref be the result of evaluating X.”, then X is some expression that you need to find the evaluation steps for. For example, evaluating a MemberExpression or CallExpression is the result of one of these algorithms. Some of them result in a Reference Record.
4: There are also several other native and host methods that allow providing a this value, notably Array.prototype.map, Array.prototype.forEach, etc. that accept a thisArg as their second argument. Anyone can make their own methods to alter this like (func, thisArg) => func.bind(thisArg), (func, thisArg) => func.call(thisArg), etc. As always, MDN offers great documentation.
Just for fun, test your understanding with some examples
For each code snippet, answer the question: “What is the value of this at the marked line? Why?”.
To reveal the answers, click the gray boxes.
if(true){
console.log(this); // What is `this` here?
}
globalThis. The marked line is evaluated in the initial global execution context.
const obj = {};
function myFun(){
return { // What is `this` here?
"is obj": this === obj,
"is globalThis": this === globalThis
};
}
obj.method = myFun;
console.log(obj.method());
obj. When calling a function as a property of an object, it is called with the this binding set to the base of the reference obj.method, i.e. obj.
const obj = {
myMethod: function(){
return { // What is `this` here?
"is obj": this === obj,
"is globalThis": this === globalThis
};
}
},
myFun = obj.myMethod;
console.log(myFun());
globalThis. Since the function value myFun / obj.myMethod is not called off of an object, as a property, the this binding will be globalThis.
This is different from Python, in which accessing a method (obj.myMethod) creates a bound method object.
const obj = {
myFun: () => ({ // What is `this` here?
"is obj": this === obj,
"is globalThis": this === globalThis
})
};
console.log(obj.myFun());
globalThis. Arrow functions don’t create their own this binding. The lexical scope is the same as the initial global scope, so this is globalThis.
function myFun(){
console.log(this); // What is `this` here?
}
const obj = {
myMethod: function(){
eval("myFun()");
}
};
obj.myMethod();
globalThis. When evaluating the direct eval call, this is obj. However, in the eval code, myFun is not called off of an object, so the this binding is set to the global object.
function myFun() {
// What is `this` here?
return {
"is obj": this === obj,
"is globalThis": this === globalThis
};
}
const obj = {};
console.log(myFun.call(obj));
obj. The line myFun.call(obj); is invoking the special built-in function Function.prototype.call, which accepts thisArg as the first argument.
class MyCls{
arrow = () => ({ // What is `this` here?
"is MyCls": this === MyCls,
"is globalThis": this === globalThis,
"is instance": this instanceof MyCls
});
}
console.log(new MyCls().arrow());
It’s the instance of MyCls. Arrow functions don’t change the this binding, so it comes from lexical scope. Therefore, this is exactly the same as with the class fields mentioned above, like a = this;. Try changing it to static arrow. Do you get the result you expect?
The this keyword behaves differently in JavaScript compared to other languages. In Object Oriented languages, the this keyword refers to the current instance of the class. In JavaScript the value of this is determined by the invocation context of function (context.function()) and where it is called.
1. When used in global context
When you use this in global context, it is bound to global object (window in browser)
document.write(this); //[object Window]
When you use this inside a function defined in the global context, this is still bound to global object since the function is actually made a method of global context.
function f1()
{
return this;
}
document.write(f1()); //[object Window]
Above f1 is made a method of global object. Thus we can also call it on window object as follows:
function f()
{
return this;
}
document.write(window.f()); //[object Window]
2. When used inside object method
When you use this keyword inside an object method, this is bound to the "immediate" enclosing object.
var obj = {
name: "obj",
f: function () {
return this + ":" + this.name;
}
};
document.write(obj.f()); //[object Object]:obj
Above I have put the word immediate in double quotes. It is to make the point that if you nest the object inside another object, then this is bound to the immediate parent.
var obj = {
name: "obj1",
nestedobj: {
name:"nestedobj",
f: function () {
return this + ":" + this.name;
}
}
}
document.write(obj.nestedobj.f()); //[object Object]:nestedobj
Even if you add function explicitly to the object as a method, it still follows above rules, that is this still points to the immediate parent object.
var obj1 = {
name: "obj1",
}
function returnName() {
return this + ":" + this.name;
}
obj1.f = returnName; //add method to object
document.write(obj1.f()); //[object Object]:obj1
3. When invoking context-less function
When you use this inside function that is invoked without any context (i.e. not on any object), it is bound to the global object (window in browser)(even if the function is defined inside the object) .
var context = "global";
var obj = {
context: "object",
method: function () {
function f() {
var context = "function";
return this + ":" +this.context;
};
return f(); //invoked without context
}
};
document.write(obj.method()); //[object Window]:global
Trying it all with functions
We can try above points with functions too. However there are some differences.
Above we added members to objects using object literal notation. We can add members to functions by using this. to specify them.
Object literal notation creates an instance of object which we can use immediately. With function we may need to first create its instance using new operator.
Also in an object literal approach, we can explicitly add members to already defined object using dot operator. This gets added to the specific instance only. However I have added variable to the function prototype so that it gets reflected in all instances of the function.
Below I tried out all the things that we did with Object and this above, but by first creating function instead of directly writing an object.
/*********************************************************************
1. When you add variable to the function using this keyword, it
gets added to the function prototype, thus allowing all function
instances to have their own copy of the variables added.
*********************************************************************/
function functionDef()
{
this.name = "ObjDefinition";
this.getName = function(){
return this+":"+this.name;
}
}
obj1 = new functionDef();
document.write(obj1.getName() + "<br />"); //[object Object]:ObjDefinition
/*********************************************************************
2. Members explicitly added to the function protorype also behave
as above: all function instances have their own copy of the
variable added.
*********************************************************************/
functionDef.prototype.version = 1;
functionDef.prototype.getVersion = function(){
return "v"+this.version; //see how this.version refers to the
//version variable added through
//prototype
}
document.write(obj1.getVersion() + "<br />"); //v1
/*********************************************************************
3. Illustrating that the function variables added by both above
ways have their own copies across function instances
*********************************************************************/
functionDef.prototype.incrementVersion = function(){
this.version = this.version + 1;
}
var obj2 = new functionDef();
document.write(obj2.getVersion() + "<br />"); //v1
obj2.incrementVersion(); //incrementing version in obj2
//does not affect obj1 version
document.write(obj2.getVersion() + "<br />"); //v2
document.write(obj1.getVersion() + "<br />"); //v1
/*********************************************************************
4. `this` keyword refers to the immediate parent object. If you
nest the object through function prototype, then `this` inside
object refers to the nested object not the function instance
*********************************************************************/
functionDef.prototype.nestedObj = { name: 'nestedObj',
getName1 : function(){
return this+":"+this.name;
}
};
document.write(obj2.nestedObj.getName1() + "<br />"); //[object Object]:nestedObj
/*********************************************************************
5. If the method is on an object's prototype chain, `this` refers
to the object the method was called on, as if the method was on
the object.
*********************************************************************/
var ProtoObj = { fun: function () { return this.a } };
var obj3 = Object.create(ProtoObj); //creating an object setting ProtoObj
//as its prototype
obj3.a = 999; //adding instance member to obj3
document.write(obj3.fun()+"<br />");//999
//calling obj3.fun() makes
//ProtoObj.fun() to access obj3.a as
//if fun() is defined on obj3
4. When used inside constructor function.
When the function is used as a constructor (that is when it is called with new keyword), this inside function body points to the new object being constructed.
var myname = "global context";
function SimpleFun()
{
this.myname = "simple function";
}
var obj1 = new SimpleFun(); //adds myname to obj1
//1. `new` causes `this` inside the SimpleFun() to point to the
// object being constructed thus adding any member
// created inside SimipleFun() using this.membername to the
// object being constructed
//2. And by default `new` makes function to return newly
// constructed object if no explicit return value is specified
document.write(obj1.myname); //simple function
5. When used inside function defined on prototype chain
If the method is on an object's prototype chain, this inside such method refers to the object the method was called on, as if the method is defined on the object.
var ProtoObj = {
fun: function () {
return this.a;
}
};
//Object.create() creates object with ProtoObj as its
//prototype and assigns it to obj3, thus making fun()
//to be the method on its prototype chain
var obj3 = Object.create(ProtoObj);
obj3.a = 999;
document.write(obj3.fun()); //999
//Notice that fun() is defined on obj3's prototype but
//`this.a` inside fun() retrieves obj3.a
6. Inside call(), apply() and bind() functions
All these methods are defined on Function.prototype.
These methods allows to write a function once and invoke it in different context. In other words, they allows to specify the value of this which will be used while the function is being executed. They also take any parameters to be passed to the original function when it is invoked.
fun.apply(obj1 [, argsArray]) Sets obj1 as the value of this inside fun() and calls fun() passing elements of argsArray as its arguments.
fun.call(obj1 [, arg1 [, arg2 [,arg3 [, ...]]]]) - Sets obj1 as the value of this inside fun() and calls fun() passing arg1, arg2, arg3, ... as its arguments.
fun.bind(obj1 [, arg1 [, arg2 [,arg3 [, ...]]]]) - Returns the reference to the function fun with this inside fun bound to obj1 and parameters of fun bound to the parameters specified arg1, arg2, arg3,....
By now the difference between apply, call and bind must have become apparent. apply allows to specify the arguments to function as array-like object i.e. an object with a numeric length property and corresponding non-negative integer properties. Whereas call allows to specify the arguments to the function directly. Both apply and call immediately invokes the function in the specified context and with the specified arguments. On the other hand, bind simply returns the function bound to the specified this value and the arguments. We can capture the reference to this returned function by assigning it to a variable and later we can call it any time.
function add(inc1, inc2)
{
return this.a + inc1 + inc2;
}
var o = { a : 4 };
document.write(add.call(o, 5, 6)+"<br />"); //15
//above add.call(o,5,6) sets `this` inside
//add() to `o` and calls add() resulting:
// this.a + inc1 + inc2 =
// `o.a` i.e. 4 + 5 + 6 = 15
document.write(add.apply(o, [5, 6]) + "<br />"); //15
// `o.a` i.e. 4 + 5 + 6 = 15
var g = add.bind(o, 5, 6); //g: `o.a` i.e. 4 + 5 + 6
document.write(g()+"<br />"); //15
var h = add.bind(o, 5); //h: `o.a` i.e. 4 + 5 + ?
document.write(h(6) + "<br />"); //15
// 4 + 5 + 6 = 15
document.write(h() + "<br />"); //NaN
//no parameter is passed to h()
//thus inc2 inside add() is `undefined`
//4 + 5 + undefined = NaN</code>
7. this inside event handlers
When you assign function directly to event handlers of an element, use of this directly inside event handling function refers to the corresponding element. Such direct function assignment can be done using addeventListener method or through the traditional event registration methods like onclick.
Similarly, when you use this directly inside the event property (like <button onclick="...this..." >) of the element, it refers to the element.
However use of this indirectly through the other function called inside the event handling function or event property resolves to the global object window.
The same above behavior is achieved when we attach the function to the event handler using Microsoft's Event Registration model method attachEvent. Instead of assigning the function to the event handler (and the thus making the function method of the element), it calls the function on the event (effectively calling it in global context).
I recommend to better try this in JSFiddle.
<script>
function clickedMe() {
alert(this + " : " + this.tagName + " : " + this.id);
}
document.getElementById("button1").addEventListener("click", clickedMe, false);
document.getElementById("button2").onclick = clickedMe;
document.getElementById("button5").attachEvent('onclick', clickedMe);
</script>
<h3>Using `this` "directly" inside event handler or event property</h3>
<button id="button1">click() "assigned" using addEventListner() </button><br />
<button id="button2">click() "assigned" using click() </button><br />
<button id="button3" onclick="alert(this+ ' : ' + this.tagName + ' : ' + this.id);">used `this` directly in click event property</button>
<h3>Using `this` "indirectly" inside event handler or event property</h3>
<button onclick="alert((function(){return this + ' : ' + this.tagName + ' : ' + this.id;})());">`this` used indirectly, inside function <br /> defined & called inside event property</button><br />
<button id="button4" onclick="clickedMe()">`this` used indirectly, inside function <br /> called inside event property</button> <br />
IE only: <button id="button5">click() "attached" using attachEvent() </button>
8. this in ES6 arrow function
In an arrow function, this will behave like common variables: it will be inherited from its lexical scope. The function's this, where the arrow function is defined, will be the arrow function's this.
So, that's the same behavior as:
(function(){}).bind(this)
See the following code:
const globalArrowFunction = () => {
return this;
};
console.log(globalArrowFunction()); //window
const contextObject = {
method1: () => {return this},
method2: function(){
return () => {return this};
}
};
console.log(contextObject.method1()); //window
const contextLessFunction = contextObject.method1;
console.log(contextLessFunction()); //window
console.log(contextObject.method2()()) //contextObject
const innerArrowFunction = contextObject.method2();
console.log(innerArrowFunction()); //contextObject
Javascript's this
Simple function invocation
Consider the following function:
function foo() {
console.log("bar");
console.log(this);
}
foo(); // calling the function
Note that we are running this in the normal mode, i.e. strict mode is not used.
When running in a browser, the value of this would be logged as window. This is because window is the global variable in a web browser's scope.
If you run this same piece of code in an environment like node.js, this would refer to the global variable in your app.
Now if we run this in strict mode by adding the statement "use strict"; to the beginning of the function declaration, this would no longer refer to the global variable in either of the environments. This is done to avoid confusions in strict mode. this would, in this case just log undefined, because that is what it is, it is not defined.
In the following cases, we would see how to manipulate the value of this.
Calling a function on an object
There are different ways to do this. If you have called native methods in Javascript like forEach and slice, you should already know that the this variable in that case refers to the Object on which you called that function (Note that in javascript, just about everything is an Object, including Arrays and Functions). Take the following code for example.
var myObj = {key: "Obj"};
myObj.logThis = function () {
// I am a method
console.log(this);
}
myObj.logThis(); // myObj is logged
If an Object contains a property which holds a Function, the property is called a method. This method, when called, will always have it's this variable set to the Object it is associated with. This is true for both strict and non-strict modes.
Note that if a method is stored (or rather, copied) in another variable, the reference to this is no longer preserved in the new variable. For example:
// continuing with the previous code snippet
var myVar = myObj.logThis;
myVar();
// logs either of window/global/undefined based on mode of operation
Considering a more commonly practical scenario:
var el = document.getElementById('idOfEl');
el.addEventListener('click', function() { console.log(this) });
// the function called by addEventListener contains this as the reference to the element
// so clicking on our element would log that element itself
The new keyword
Consider a constructor function in Javascript:
function Person (name) {
this.name = name;
this.sayHello = function () {
console.log ("Hello", this);
}
}
var awal = new Person("Awal");
awal.sayHello();
// In `awal.sayHello`, `this` contains the reference to the variable `awal`
How does this work? Well, let's see what happens when we use the new keyword.
Calling the function with the new keyword would immediately initialize an Object of type Person.
The constructor of this Object has its constructor set to Person. Also, note that typeof awal would return Object only.
This new Object would be assigned the prototype of Person.prototype. This means that any method or property in the Person prototype would be available to all instances of Person, including awal.
The function Person itself is now invoked; this being a reference to the newly constructed object awal.
Pretty straightforward, eh?
Note that the official ECMAScript spec nowhere states that such types of functions are actual constructor functions. They are just normal functions, and new can be used on any function. It's just that we use them as such, and so we call them as such only.
Calling functions on Functions: call and apply
So yeah, since functions are also Objects (and in-fact first class variables in Javascript), even functions have methods which are... well, functions themselves.
All functions inherit from the global Function, and two of its many methods are call and apply, and both can be used to manipulate the value of this in the function on which they are called.
function foo () { console.log (this, arguments); }
var thisArg = {myObj: "is cool"};
foo.call(thisArg, 1, 2, 3);
This is a typical example of using call. It basically takes the first parameter and sets this in the function foo as a reference to thisArg. All other parameters passed to call is passed to the function foo as arguments.
So the above code will log {myObj: "is cool"}, [1, 2, 3] in the console. Pretty nice way to change the value of this in any function.
apply is almost the same as call accept that it takes only two parameters: thisArg and an array which contains the arguments to be passed to the function. So the above call call can be translated to apply like this:
foo.apply(thisArg, [1,2,3])
Note that call and apply can override the value of this set by dot method invocation we discussed in the second bullet.
Simple enough :)
Presenting.... bind!
bind is a brother of call and apply. It is also a method inherited by all functions from the global Function constructor in Javascript. The difference between bind and call/apply is that both call and apply will actually invoke the function. bind, on the other hand, returns a new function with the thisArg and arguments pre-set. Let's take an example to better understand this:
function foo (a, b) {
console.log (this, arguments);
}
var thisArg = {myObj: "even more cool now"};
var bound = foo.bind(thisArg, 1, 2);
console.log (typeof bound); // logs `function`
console.log (bound);
/* logs `function () { native code }` */
bound(); // calling the function returned by `.bind`
// logs `{myObj: "even more cool now"}, [1, 2]`
See the difference between the three? It is subtle, but they are used differently. Like call and apply, bind will also over-ride the value of this set by dot-method invocation.
Also note that neither of these three functions do any change to the original function. call and apply would return the value from freshly constructed functions while bind will return the freshly constructed function itself, ready to be called.
Extra stuff, copy this
Sometimes, you don't like the fact that this changes with scope, especially nested scope. Take a look at the following example.
var myObj = {
hello: function () {
return "world"
},
myMethod: function () {
// copy this, variable names are case-sensitive
var that = this;
// callbacks ftw \o/
foo.bar("args", function () {
// I want to call `hello` here
this.hello(); // error
// but `this` references to `foo` damn!
// oh wait we have a backup \o/
that.hello(); // "world"
});
}
};
In the above code, we see that the value of this changed with the nested scope, but we wanted the value of this from the original scope. So we 'copied' this to that and used the copy instead of this. Clever, eh?
Index:
What is held in this by default?
What if we call the function as a method with Object-dot notation?
What if we use the new keyword?
How do we manipulate this with call and apply?
Using bind.
Copying this to solve nested-scope issues.
"this" is all about scope. Every function has its own scope, and since everything in JS is an object, even a function can store some values into itself using "this". OOP 101 teaches that "this" is only applicable to instances of an object. Therefore, every-time a function executes, a new "instance" of that function has a new meaning of "this".
Most people get confused when they try to use "this" inside of anonymous closure functions like:
(function(value) {
this.value = value;
$('.some-elements').each(function(elt){
elt.innerHTML = this.value; // uh oh!! possibly undefined
});
})(2);
So here, inside each(), "this" doesn't hold the "value" that you expect it to (from this.value = value; above it). So, to get over this (no pun intended) problem, a developer could:
(function(value) {
var self = this; // small change
self.value = value;
$('.some-elements').each(function(elt){
elt.innerHTML = self.value; // phew!! == 2
});
})(2);
Try it out; you'll begin to like this pattern of programming
Since this thread has bumped up, I have compiled few points for readers new to this topic.
How is the value of this determined?
We use this similar to the way we use pronouns in natural languages like English: “John is running fast because he is trying to catch the train.” Instead we could have written “… John is trying to catch the train”.
var person = {
firstName: "Penelope",
lastName: "Barrymore",
fullName: function () {
// We use "this" just as in the sentence above:
console.log(this.firstName + " " + this.lastName);
// We could have also written:
console.log(person.firstName + " " + person.lastName);
}
}
this is not assigned a value until an object invokes the function where it is defined. In the global scope, all global variables and functions are defined on the window object. Therefore, this in a global function refers to (and has the value of) the global window object.
When use strict, this in global and in anonymous functions that are not bound to any object holds a value of undefined.
The this keyword is most misunderstood when: 1) we borrow a method that uses this, 2) we assign a method that uses this to a variable, 3) a function that uses this is passed as a callback function, and 4) this is used inside a closure — an inner function. (2)
What holds the future
Defined in ECMA Script 6, arrow-functions adopt the this binding from the
enclosing (function or global) scope.
function foo() {
// return an arrow function
return (a) => {
// `this` here is lexically inherited from `foo()`
console.log(this.a);
};
}
var obj1 = { a: 2 };
var obj2 = { a: 3 };
var bar = foo.call(obj1);
bar.call( obj2 ); // 2, not 3!
While arrow-functions provide an alternative to using bind(), it’s important to note that they essentially are disabling the traditional this mechanism in favor of more widely understood lexical scoping. (1)
References:
this & Object Prototypes, by Kyle Simpson. © 2014 Getify Solutions.
javascriptissexy.com - http://goo.gl/pvl0GX
Angus Croll - http://goo.gl/Z2RacU
this in JavaScript always refers to the 'owner' of the function that is being executed.
If no explicit owner is defined, then the top most owner, the window object, is referenced.
So if I did
function someKindOfFunction() {
this.style = 'foo';
}
element.onclick = someKindOfFunction;
this would refer to the element object. But be careful, a lot of people make this mistake.
<element onclick="someKindOfFunction()">
In the latter case, you merely reference the function, not hand it over to the element. Therefore, this will refer to the window object.
Every execution context in javascript has a this parameter that is set by:
How the function is called (including as an object method, use of call and apply, use of new)
Use of bind
Lexically for arrow functions (they adopt the this of their outer execution context)
Whether the code is in strict or non-strict mode
Whether the code was invoked using eval
You can set the value of this using func.call, func.apply or func.bind.
By default, and what confuses most beginners, when a listener is called after an event is raised on a DOM element, the this value of the function is the DOM element.
jQuery makes this trivial to change with jQuery.proxy.
Daniel, awesome explanation! A couple of words on this and good list of this execution context pointer in case of event handlers.
In two words, this in JavaScript points the object from whom (or from whose execution context) the current function was run and it's always read-only, you can't set it anyway (such an attempt will end up with 'Invalid left-hand side in assignment' message.
For event handlers: inline event handlers, such as <element onclick="foo">, override any other handlers attached earlier and before, so be careful and it's better to stay off of inline event delegation at all.
And thanks to Zara Alaverdyan who inspired me to this list of examples through a dissenting debate :)
el.onclick = foo; // in the foo - obj
el.onclick = function () {this.style.color = '#fff';} // obj
el.onclick = function() {doSomething();} // In the doSomething -
Window
el.addEventListener('click',foo,false) // in the foo - obj
el.attachEvent('onclick, function () { // this }') // window, all the
compliance to IE :)
<button onclick="this.style.color = '#fff';"> // obj
<button onclick="foo"> // In the foo - window, but you can <button
onclick="foo(this)">
Here is one good source of this in JavaScript.
Here is the summary:
global this
In a browser, at the global scope, this is the windowobject
<script type="text/javascript">
console.log(this === window); // true
var foo = "bar";
console.log(this.foo); // "bar"
console.log(window.foo); // "bar"
In node using the repl, this is the top namespace. You can refer to it as global.
>this
{ ArrayBuffer: [Function: ArrayBuffer],
Int8Array: { [Function: Int8Array] BYTES_PER_ELEMENT: 1 },
Uint8Array: { [Function: Uint8Array] BYTES_PER_ELEMENT: 1 },
...
>global === this
true
In node executing from a script, this at the global scope starts as an empty object. It is not the same as global
\\test.js
console.log(this); \\ {}
console.log(this === global); \\ fasle
function this
Except in the case of DOM event handlers or when a thisArg is provided (see further down), both in node and in a browser using this in a function that is not called with new references the global scope…
<script type="text/javascript">
foo = "bar";
function testThis() {
this.foo = "foo";
}
console.log(this.foo); //logs "bar"
testThis();
console.log(this.foo); //logs "foo"
</script>
If you use use strict;, in which case this will be undefined
<script type="text/javascript">
foo = "bar";
function testThis() {
"use strict";
this.foo = "foo";
}
console.log(this.foo); //logs "bar"
testThis(); //Uncaught TypeError: Cannot set property 'foo' of undefined
</script>
If you call a function with new the this will be a new context, it will not reference the global this.
<script type="text/javascript">
foo = "bar";
function testThis() {
this.foo = "foo";
}
console.log(this.foo); //logs "bar"
new testThis();
console.log(this.foo); //logs "bar"
console.log(new testThis().foo); //logs "foo"
</script>
prototype this
Functions you create become function objects. They automatically get a special prototype property, which is something you can assign values to. When you create an instance by calling your function with new you get access to the values you assigned to the prototype property. You access those values using this.
function Thing() {
console.log(this.foo);
}
Thing.prototype.foo = "bar";
var thing = new Thing(); //logs "bar"
console.log(thing.foo); //logs "bar"
It is usually a mistake to assign arrays or objects on the prototype. If you want instances to each have their own arrays, create them in the function, not the prototype.
function Thing() {
this.things = [];
}
var thing1 = new Thing();
var thing2 = new Thing();
thing1.things.push("foo");
console.log(thing1.things); //logs ["foo"]
console.log(thing2.things); //logs []
object this
You can use this in any function on an object to refer to other properties on that object. This is not the same as an instance created with new.
var obj = {
foo: "bar",
logFoo: function () {
console.log(this.foo);
}
};
obj.logFoo(); //logs "bar"
DOM event this
In an HTML DOM event handler, this is always a reference to the DOM element the event was attached to
function Listener() {
document.getElementById("foo").addEventListener("click",
this.handleClick);
}
Listener.prototype.handleClick = function (event) {
console.log(this); //logs "<div id="foo"></div>"
}
var listener = new Listener();
document.getElementById("foo").click();
Unless you bind the context
function Listener() {
document.getElementById("foo").addEventListener("click",
this.handleClick.bind(this));
}
Listener.prototype.handleClick = function (event) {
console.log(this); //logs Listener {handleClick: function}
}
var listener = new Listener();
document.getElementById("foo").click();
HTML this
Inside HTML attributes in which you can put JavaScript, this is a reference to the element.
<div id="foo" onclick="console.log(this);"></div>
<script type="text/javascript">
document.getElementById("foo").click(); //logs <div id="foo"...
</script>
eval this
You can use eval to access this.
function Thing () {
}
Thing.prototype.foo = "bar";
Thing.prototype.logFoo = function () {
eval("console.log(this.foo)"); //logs "bar"
}
var thing = new Thing();
thing.logFoo();
with this
You can use with to add this to the current scope to read and write to values on this without referring to this explicitly.
function Thing () {
}
Thing.prototype.foo = "bar";
Thing.prototype.logFoo = function () {
with (this) {
console.log(foo);
foo = "foo";
}
}
var thing = new Thing();
thing.logFoo(); // logs "bar"
console.log(thing.foo); // logs "foo"
jQuery this
the jQuery will in many places have this refer to a DOM element.
<div class="foo bar1"></div>
<div class="foo bar2"></div>
<script type="text/javascript">
$(".foo").each(function () {
console.log(this); //logs <div class="foo...
});
$(".foo").on("click", function () {
console.log(this); //logs <div class="foo...
});
$(".foo").each(function () {
this.click();
});
</script>
There is a lot of confusion regarding how "this" keyword is interpreted in JavaScript. Hopefully this article will lay all those to rest once and for all. And a lot more. Please read the entire article carefully. Be forewarned that this article is long.
Irrespective of the context in which it is used, "this" always references the "current object" in Javascript. However, what the "current object" is differs according to context. The context may be exactly 1 of the 6 following:
Global (i.e. Outside all functions)
Inside Direct "Non Bound Function" Call (i.e. a function that has not been bound by calling functionName.bind)
Inside Indirect "Non Bound Function" Call through functionName.call and functionName.apply
Inside "Bound Function" Call (i.e. a function that has been bound by calling functionName.bind)
While Object Creation through "new"
Inside Inline DOM event handler
The following describes each of this contexts one by one:
Global Context (i.e. Outside all functions):
Outside all functions (i.e. in global context) the "current
object" (and hence the value of "this") is always the
"window" object for browsers.
Inside Direct "Non Bound Function" Call:
Inside a Direct "Non Bound Function" Call, the object that
invoked the function call becomes the "current object" (and hence
the value of "this"). If a function is called without a explicit current object, the current object is either the "window" object (For Non Strict Mode) or undefined (For Strict Mode) . Any function (or variable) defined in
Global Context automatically becomes a property of the "window" object.For e.g Suppose function is defined in Global Context as
function UserDefinedFunction(){
alert(this)
}
it becomes the property of the window object, as if you have defined
it as
window.UserDefinedFunction=function(){
alert(this)
}
In "Non Strict Mode", Calling/Invoking this function directly through "UserDefinedFunction()" will automatically call/invoke
it as "window.UserDefinedFunction()" making "window" as the
"current object" (and hence the value of "this") within "UserDefinedFunction".Invoking this function in "Non Strict Mode" will result in the following
UserDefinedFunction() // displays [object Window] as it automatically gets invoked as window.UserDefinedFunction()
In "Strict Mode", Calling/Invoking the function directly through
"UserDefinedFunction()" will "NOT" automatically call/invoke it as "window.UserDefinedFunction()".Hence the "current
object" (and the value of "this") within
"UserDefinedFunction" shall be undefined. Invoking this function in "Strict Mode" will result in the following
UserDefinedFunction() // displays undefined
However, invoking it explicitly using window object shall result in
the following
window.UserDefinedFunction() // "always displays [object Window] irrespective of mode."
Let us look at another example. Please look at the following code
function UserDefinedFunction()
{
alert(this.a + "," + this.b + "," + this.c + "," + this.d)
}
var o1={
a:1,
b:2,
f:UserDefinedFunction
}
var o2={
c:3,
d:4,
f:UserDefinedFunction
}
o1.f() // Shall display 1,2,undefined,undefined
o2.f() // Shall display undefined,undefined,3,4
In the above example we see that when "UserDefinedFunction" was
invoked through o1, "this" takes value of o1 and the
value of its properties "a" and "b" get displayed. The value
of "c" and "d" were shown as undefined as o1 does
not define these properties
Similarly when "UserDefinedFunction" was invoked through o2,
"this" takes value of o2 and the value of its properties "c" and "d" get displayed.The value of "a" and "b" were shown as undefined as o2 does not define these properties.
Inside Indirect "Non Bound Function" Call through functionName.call and functionName.apply:
When a "Non Bound Function" is called through
functionName.call or functionName.apply, the "current object" (and hence the value of "this") is set to the value of
"this" parameter (first parameter) passed to call/apply. The following code demonstrates the same.
function UserDefinedFunction()
{
alert(this.a + "," + this.b + "," + this.c + "," + this.d)
}
var o1={
a:1,
b:2,
f:UserDefinedFunction
}
var o2={
c:3,
d:4,
f:UserDefinedFunction
}
UserDefinedFunction.call(o1) // Shall display 1,2,undefined,undefined
UserDefinedFunction.apply(o1) // Shall display 1,2,undefined,undefined
UserDefinedFunction.call(o2) // Shall display undefined,undefined,3,4
UserDefinedFunction.apply(o2) // Shall display undefined,undefined,3,4
o1.f.call(o2) // Shall display undefined,undefined,3,4
o1.f.apply(o2) // Shall display undefined,undefined,3,4
o2.f.call(o1) // Shall display 1,2,undefined,undefined
o2.f.apply(o1) // Shall display 1,2,undefined,undefined
The above code clearly shows that the "this" value for any "NON
Bound Function" can be altered through call/apply. Also,if the
"this" parameter is not explicitly passed to call/apply, "current object" (and hence the value of "this") is set to "window" in Non strict mode and "undefined" in strict mode.
Inside "Bound Function" Call (i.e. a function that has been bound by calling functionName.bind):
A bound function is a function whose "this" value has been
fixed. The following code demonstrated how "this" works in case
of bound function
function UserDefinedFunction()
{
alert(this.a + "," + this.b + "," + this.c + "," + this.d)
}
var o1={
a:1,
b:2,
f:UserDefinedFunction,
bf:null
}
var o2={
c:3,
d:4,
f:UserDefinedFunction,
bf:null
}
var bound1=UserDefinedFunction.bind(o1); // permanantly fixes "this" value of function "bound1" to Object o1
bound1() // Shall display 1,2,undefined,undefined
var bound2=UserDefinedFunction.bind(o2); // permanantly fixes "this" value of function "bound2" to Object o2
bound2() // Shall display undefined,undefined,3,4
var bound3=o1.f.bind(o2); // permanantly fixes "this" value of function "bound3" to Object o2
bound3() // Shall display undefined,undefined,3,4
var bound4=o2.f.bind(o1); // permanantly fixes "this" value of function "bound4" to Object o1
bound4() // Shall display 1,2,undefined,undefined
o1.bf=UserDefinedFunction.bind(o2) // permanantly fixes "this" value of function "o1.bf" to Object o2
o1.bf() // Shall display undefined,undefined,3,4
o2.bf=UserDefinedFunction.bind(o1) // permanantly fixes "this" value of function "o2.bf" to Object o1
o2.bf() // Shall display 1,2,undefined,undefined
bound1.call(o2) // Shall still display 1,2,undefined,undefined. "call" cannot alter the value of "this" for bound function
bound1.apply(o2) // Shall still display 1,2,undefined,undefined. "apply" cannot alter the value of "this" for bound function
o2.bf.call(o2) // Shall still display 1,2,undefined,undefined. "call" cannot alter the value of "this" for bound function
o2.bf.apply(o2) // Shall still display 1,2,undefined,undefined."apply" cannot alter the value of "this" for bound function
As given in the code above, "this" value for any "Bound Function"
CANNOT be altered through call/apply. Also, if the "this"
parameter is not explicitly passed to bind, "current object"
(and hence the value of "this" ) is set to "window" in Non
strict mode and "undefined" in strict mode. One more thing.
Binding an already bound function does not change the value of "this".
It remains set as the value set by first bind function.
While Object Creation through "new":
Inside a constructor function, the "current object" (and hence the value of
"this") references the object that is currently being created
through "new" irrespective of the bind status of the function. However
if the constructor is a bound function it shall get called with
predefined set of arguments as set for the bound function.
Inside Inline DOM event handler:
Please look at the following HTML Snippet
<button onclick='this.style.color=white'>Hello World</button>
<div style='width:100px;height:100px;' onclick='OnDivClick(event,this)'>Hello World</div>
The "this" in above examples refer to "button" element and the
"div" element respectively.
In the first example, the font color of the button shall be set to
white when it is clicked.
In the second example when the "div" element is clicked it shall
call the OnDivClick function with its second parameter
referencing the clicked div element. However the value of "this"
within OnDivClick SHALL NOT reference the clicked div
element. It shall be set as the "window object" or
"undefined" in Non strict and Strict Modes respectively (if OnDivClick is an unbound function) or set to a predefined
Bound value (if OnDivClick is a bound function)
The following summarizes the entire article
In Global Context "this" always refers to the "window" object
Whenever a function is invoked, it is invoked in context of an
object ("current object"). If the current object is not explicitly provided,
the current object is the "window object" in NON Strict
Mode and "undefined" in Strict Mode by default.
The value of "this" within a Non Bound function is the reference to object in context of which the function is invoked ("current object")
The value of "this" within a Non Bound function can be overriden by
call and apply methods of the function.
The value of "this" is fixed for a Bound function and cannot be
overriden by call and apply methods of the function.
Binding and already bound function does not change the value of "this". It remains set as the value set by first bind function.
The value of "this" within a constructor is the object that is being
created and initialized
The value of "this" within an inline DOM event handler is reference
to the element for which the event handler is given.
Probably the most detailed and comprehensive article on this is the following:
Gentle explanation of 'this' keyword in JavaScript
The idea behind this is to understand that the function invocation types have the significant importance on setting this value.
When having troubles identifying this, do not ask yourself:
Where is this taken from?
but do ask yourself:
How is the function invoked?
For an arrow function (special case of context transparency) ask yourself:
What value has this where the arrow function is defined?
This mindset is correct when dealing with this and will save you from headache.
This is the best explanation I've seen: Understand JavaScripts this with Clarity
The this reference ALWAYS refers to (and holds the value of) an
object—a singular object—and it is usually used inside a function or a
method, although it can be used outside a function in the global
scope. Note that when we use strict mode, this holds the value of
undefined in global functions and in anonymous functions that are not
bound to any object.
There are Four Scenarios where this can be confusing:
When we pass a method (that uses this) as an argument to be used as a callback function.
When we use an inner function (a closure). It is important to take note that closures cannot access the outer function’s this variable by using the this keyword because the this variable is accessible only by the function itself, not by inner functions.
When a method which relies on this is assigned to a variable across contexts, in which case this references another object than originally intended.
When using this along with the bind, apply, and call methods.
He gives code examples, explanations, and solutions, which I thought was very helpful.
this is one of the misunderstood concept in JavaScript because it behaves little differently from place to place. Simply, this refers to the "owner" of the function we are currently executing.
this helps to get the current object (a.k.a. execution context) we work with. If you understand in which object the current function is getting executed, you can understand easily what current this is
var val = "window.val"
var obj = {
val: "obj.val",
innerMethod: function () {
var val = "obj.val.inner",
func = function () {
var self = this;
return self.val;
};
return func;
},
outerMethod: function(){
return this.val;
}
};
//This actually gets executed inside window object
console.log(obj.innerMethod()()); //returns window.val
//Breakdown in to 2 lines explains this in detail
var _inn = obj.innerMethod();
console.log(_inn()); //returns window.val
console.log(obj.outerMethod()); //returns obj.val
Above we create 3 variables with same name 'val'. One in global context, one inside obj and the other inside innerMethod of obj. JavaScript resolves identifiers within a particular context by going up the scope chain from local go global.
Few places where this can be differentiated
Calling a method of a object
var status = 1;
var helper = {
status : 2,
getStatus: function () {
return this.status;
}
};
var theStatus1 = helper.getStatus(); //line1
console.log(theStatus1); //2
var theStatus2 = helper.getStatus;
console.log(theStatus2()); //1
When line1 is executed, JavaScript establishes an execution context (EC) for the function call, setting this to the object referenced by whatever came before the last ".". so in the last line you can understand that a() was executed in the global context which is the window.
With Constructor
this can be used to refer to the object being created
function Person(name){
this.personName = name;
this.sayHello = function(){
return "Hello " + this.personName;
}
}
var person1 = new Person('Scott');
console.log(person1.sayHello()); //Hello Scott
var person2 = new Person('Hugh');
var sayHelloP2 = person2.sayHello;
console.log(sayHelloP2()); //Hello undefined
When new Person() is executed, a completely new object is created. Person is called and its this is set to reference that new object.
Function call
function testFunc() {
this.name = "Name";
this.myCustomAttribute = "Custom Attribute";
return this;
}
var whatIsThis = testFunc();
console.log(whatIsThis); //window
var whatIsThis2 = new testFunc();
console.log(whatIsThis2); //testFunc() / object
console.log(window.myCustomAttribute); //Custom Attribute
If we miss new keyword, whatIsThis referes to the most global context it can find(window)
With event handlers
If the event handler is inline, this refers to global object
<script type="application/javascript">
function click_handler() {
alert(this); // alerts the window object
}
</script>
<button id='thebutton' onclick='click_handler()'>Click me!</button>
When adding event handler through JavaScript, this refers to DOM element that generated the event.
You can also manipulate the context using .apply() .call() and .bind()
JQuery proxy is another way you can use to make sure this in a function will be the value you desire. (Check Understanding $.proxy(), jQuery.proxy() usage)
What does var that = this means in JavaScript
The value of "this" depends on the "context" in which the function is executed. The context can be any object or the global object, i.e., window.
So the Semantic of "this" is different from the traditional OOP languages. And it causes problems:
1. when a function is passed to another variable (most likely, a callback); and 2. when a closure is invoked from a member method of a class.
In both cases, this is set to window.
In pseudoclassical terms, the way many lectures teach the 'this' keyword is as an object instantiated by a class or object constructor. Each time a new object is constructed from a class, imagine that under the hood a local instance of a 'this' object is created and returned. I remember it taught like this:
function Car(make, model, year) {
var this = {}; // under the hood, so to speak
this.make = make;
this.model = model;
this.year = year;
return this; // under the hood
}
var mycar = new Car('Eagle', 'Talon TSi', 1993);
// ========= under the hood
var this = {};
this.make = 'Eagle';
this.model = 'Talon TSi';
this.year = 1993;
return this;
Whould this help? (Most confusion of 'this' in javascript is coming from the fact that it generally is not linked to your object, but to the current executing scope -- that might not be exactly how it works but is always feels like that to me -- see the article for a complete explanation)
A little bit info about this keyword
Let's log this keyword to the console in global scope without any more code but
console.log(this)
In Client/Browser this keyword is a global object which is window
console.log(this === window) // true
and
In Server/Node/Javascript runtime this keyword is also a global object which is module.exports
console.log(this === module.exports) // true
console.log(this === exports) // true
Keep in mind exports is just a reference to module.exports
I have a different take on this from the other answers that I hope is helpful.
One way to look at JavaScript is to see that there are only 1 way to call a function1. It is
functionObject.call(objectForThis, arg0, arg1, arg2, ...);
There is always some value supplied for objectForThis.
Everything else is syntactic sugar for functionObject.call
So, everything else can be described by how it translates into functionObject.call.
If you just call a function then this is the "global object" which in the browser is the window
function foo() {
console.log(this);
}
foo(); // this is the window object
In other words,
foo();
was effectively translated into
foo.call(window);
Note that if you use strict mode then this will be undefined
'use strict';
function foo() {
console.log(this);
}
foo(); // this is the window object
which means
In other words,
foo();
was effectively translated into
foo.call(undefined);
In JavaScript there are operators like + and - and *. There is also the dot operator which is .
The . operator when used with a function on the right and an object on the left effectively means "pass object as this to function.
Example
const bar = {
name: 'bar',
foo() {
console.log(this);
},
};
bar.foo(); // this is bar
In other words bar.foo() translates into const temp = bar.foo; temp.call(bar);
Note that it doesn't matter how the function was created (mostly...). All of these will produce the same results
const bar = {
name: 'bar',
fn1() { console.log(this); },
fn2: function() { console.log(this); },
fn3: otherFunction,
};
function otherFunction() { console.log(this) };
bar.fn1(); // this is bar
bar.fn2(); // this is bar
bar.fn3(); // this is bar
Again these all are just syntactic sugar for
{ const temp = bar.fn1; temp.call(bar); }
{ const temp = bar.fn2; temp.call(bar); }
{ const temp = bar.fn3; temp.call(bar); }
One other wrinkle is the prototype chain. When you use a.b JavaScript first looks on the object referenced directly by a for the property b. If b is not found on the object then JavaScript will look in the object's prototype to find b.
There are various ways to define an object's prototype, the most common in 2019 is the class keyword. For the purposes of this though it doesn't matter. What matters is that as it looks in object a for property b if it finds property b on the object or in it's prototype chain if b ends up being a function then the same rules as above apply. The function b references will be called using the call method and passing a as objectForThis as shown a the top of this answer.
Now. Let's imagine we make a function that explicitly sets this before calling another function and then call it with the . (dot) operator
function foo() {
console.log(this);
}
function bar() {
const objectForThis = {name: 'moo'}
foo.call(objectForThis); // explicitly passing objectForThis
}
const obj = {
bar,
};
obj.bar();
Following the translation to use call, obj.bar() becomes const temp = obj.bar; temp.call(obj);. When we enter the bar function we call foo but we explicitly passed in another object for objectForThis so when we arrive at foo this is that inner object.
This is what both bind and => functions effectively do. They are more syntactic sugar. They effectively build a new invisible function exactly like bar above that explicitly sets this before it calls whatever function is specified. In the case of bind this is set to whatever you pass to bind.
function foo() {
console.log(this);
}
const bar = foo.bind({name: 'moo'});
// bind created a new invisible function that calls foo with the bound object.
bar();
// the objectForThis we are passing to bar here is ignored because
// the invisible function that bind created will call foo with with
// the object we bound above
bar.call({name: 'other'});
Note that if functionObject.bind did not exist we could make our own like this
function bind(fn, objectForThis) {
return function(...args) {
return fn.call(objectForthis, ...args);
};
}
and then we could call it like this
function foo() {
console.log(this);
}
const bar = bind(foo, {name:'abc'});
Arrow functions, the => operator are syntactic sugar for bind
const a = () => {console.log(this)};
is the same as
const tempFn = function() {console.log(this)};
const a = tempFn.bind(this);
Just like bind, a new invisible function is created that calls the given function with a bound value for objectForThis but unlike bind the object to be bound is implicit. It's whatever this happens to be when the => operator is used.
So, just like the rules above
const a = () => { console.log(this); } // this is the global object
'use strict';
const a = () => { console.log(this); } // this is undefined
function foo() {
return () => { console.log(this); }
}
const obj = {
foo,
};
const b = obj.foo();
b();
obj.foo() translates to const temp = obj.foo; temp.call(obj); which means the arrow operator inside foo will bind obj to a new invisible function and return that new invisible function which is assigned to b. b() will work as it always has as b.call(window) or b.call(undefined) calling the new invisible function that foo created. That invisible function ignores the this passed into it and passes obj as objectForThis` to the arrow function.
The code above translates to
function foo() {
function tempFn() {
console.log(this);
}
return tempFn.bind(this);
}
const obj = {
foo,
};
const b = obj.foo();
b.call(window or undefined if strict mode);
1apply is another function similar to call
functionName.apply(objectForThis, arrayOfArgs);
But as of ES6 conceptually you can even translate that into
functionName.call(objectForThis, ...arrayOfArgs);
"this" in JavaScript
this is one of the properties of the Execution Context.
this property is created every time a function is executed and not
before that.
Its value is not static but rather depends on how it is being used.
takes a value that points to the owner of the function in which it is
used
There are different ways in which the "this" keyword can be used, below are the example for it (method, regular function, arrow function, Event listener, Explicit function Binding).
1. Inside a method.
this === (to the object that is calling the Method).
In the above example the method " fullName()" is called by an Object "person" hence the value of this inside the method " fullName()" will be equal to the "person" Object.
2. Inside a Function.
i) function declaration/expression
in loose mode this === window (object)
in Strict mode this === undefined
Note : this property works the same while defining a function using function declaration or function expression approach.
ii) Arrow Function :
Arrow Function does not have their own this property, they take the value of this as their surrounding Function.
If the surrounding function is not present i.e if they are defined at the global level then this === window (object)
3. Event Listener
this === object on which the handler is attached.
click event bind to the Document object
In the above example since the click handler is attached to the "document" object, this will be equal to the "document" object
4. Explicit Function Binding (call, Apply, Bind)
The call() and apply() methods are predefined JavaScript methods.
They can both be used to call an object method with another object as an argument.
In the above example this inside the "printFullDetails()" is explicitly set to the personObj1 and personObj2 by passing as the first argument to call method.
You can Explore more about call, apply and bind methods here.
this use for Scope just like this
<script type="text/javascript" language="javascript">
$('#tbleName tbody tr').each(function{
var txt='';
txt += $(this).find("td").eq(0).text();
\\same as above but synatx different
var txt1='';
txt1+=$('#tbleName tbody tr').eq(0).text();
alert(txt1)
});
</script>
value of txt1 and txt is same
in Above example
$(this)=$('#tbleName tbody tr') is Same
Summary this Javascript:
The value of this is determined by how the function is invoked not, where it was created!
Usually the value of this is determined by the Object which is left of the dot. (window in global space)
In event listeners the value of this refers to the DOM element on which the event was called.
When in function is called with the new keyword the value of this refers to the newly created object
You can manipulate the value of this with the functions: call, apply, bind
Example:
let object = {
prop1: function () {console.log(this);}
}
object.prop1(); // object is left of the dot, thus this is object
const myFunction = object.prop1 // We store the function in the variable myFunction
myFunction(); // Here we are in the global space
// myFunction is a property on the global object
// Therefore it logs the window object
Example event listeners:
document.querySelector('.foo').addEventListener('click', function () {
console.log(this); // This refers to the DOM element the eventListener was invoked from
})
document.querySelector('.foo').addEventListener('click', () => {
console.log(this); // Tip, es6 arrow function don't have their own binding to the this v
}) // Therefore this will log the global object
.foo:hover {
color: red;
cursor: pointer;
}
<div class="foo">click me</div>
Example constructor:
function Person (name) {
this.name = name;
}
const me = new Person('Willem');
// When using the new keyword the this in the constructor function will refer to the newly created object
console.log(me.name);
// Therefore, the name property was placed on the object created with new keyword.
To understand "this" properly one must understand the context and scope and difference between them.
Scope: In javascript scope is related to the visibility of the variables, scope achieves through the use of the function. (Read more about scope)
Context: Context is related to objects. It refers to the object to which a function belongs. When you use the JavaScript “this” keyword, it refers to the object to which function belongs. For example, inside of a function, when you say: “this.accoutNumber”, you are referring to the property “accoutNumber”, that belongs to the object to which that function belongs.
If the object “myObj” has a method called “getMyName”, when the JavaScript keyword “this” is used inside of “getMyName”, it refers to “myObj”. If the function “getMyName” were executed in the global scope, then “this” refers to the window object (except in strict mode).
Now let's see some example:
<script>
console.log('What is this: '+this);
console.log(this);
</script>
Runnig abobve code in browser output will:
According to the output you are inside of the context of the window object, it is also visible that window prototype refers to the Object.
Now let's try inside of a function:
<script>
function myFunc(){
console.log('What is this: '+this);
console.log(this);
}
myFunc();
</script>
Output:
The output is the same because we logged 'this' variable in the global scope and we logged it in functional scope, we didn't change the context. In both case context was same, related to widow object.
Now let's create our own object. In javascript, you can create an object in many ways.
<script>
var firstName = "Nora";
var lastName = "Zaman";
var myObj = {
firstName:"Lord",
lastName:'Baron',
printNameGetContext:function(){
console.log(firstName + " "+lastName);
console.log(this.firstName +" "+this.lastName);
return this;
}
}
var context = myObj.printNameGetContext();
console.log(context);
</script>
Output:
So from the above example, we found that 'this' keyword is referring to a new context that is related to myObj, and myObject also has prototype chain to Object.
Let's go throw another example:
<body>
<button class="btn">Click Me</button>
<script>
function printMe(){
//Terminal2: this function declared inside window context so this function belongs to the window object.
console.log(this);
}
document.querySelector('.btn').addEventListener('click', function(){
//Terminal1: button context, this callback function belongs to DOM element
console.log(this);
printMe();
})
</script>
</body>
output:
Make sense right? (read comments)
If you having trouble to understand the above example let's try with our own callback;
<script>
var myObj = {
firstName:"Lord",
lastName:'Baron',
printName:function(callback1, callback2){
//Attaching callback1 with this myObj context
this.callback1 = callback1;
this.callback1(this.firstName +" "+this.lastName)
//We did not attached callback2 with myObj so, it's reamin with window context by default
callback2();
/*
//test bellow codes
this.callback2 = callback2;
this.callback2();
*/
}
}
var callback2 = function (){
console.log(this);
}
myObj.printName(function(data){
console.log(data);
console.log(this);
}, callback2);
</script>
output:
Now let's Understand Scope, Self, IIFE and THIS how behaves
var color = 'red'; // property of window
var obj = {
color:'blue', // property of window
printColor: function(){ // property of obj, attached with obj
var self = this;
console.log('In printColor -- this.color: '+this.color);
console.log('In printColor -- self.color: '+self.color);
(function(){ // decleard inside of printColor but not property of object, it will executed on window context.
console.log(this)
console.log('In IIFE -- this.color: '+this.color);
console.log('In IIFE -- self.color: '+self.color);
})();
function nestedFunc(){// decleard inside of printColor but not property of object, it will executed on window context.
console.log('nested fun -- this.color: '+this.color);
console.log('nested fun -- self.color: '+self.color);
}
nestedFunc(); // executed on window context
return nestedFunc;
}
};
obj.printColor()(); // returned function executed on window context
</script>
Output is pretty awesome right?
In my app.run I have an function which get some text from an global variable from an other file. In that variable there are some keywords with an language attribute, which allows me to only get the requested text and filter out the right language.
I made an function for that but I can't get access the $rootScope.language variable in that function which I need for getting the right text.
function getTourTranslation(key){
console.log("getTourTranslation", key);
var lang = $rootScope.language;
var step = _.get(steps, key);
return step[lang]
}
So language is undefined, and so $rootScope.language is, but the variable exists and contains the right language key for the current language on the site. How can I get the content of that variabele without passing the language as variable into the function?
I also tried as $rootScope.getTourTranslation = function(key) but no luck
edit:
This is how the language variable is filled. We use angular-translate, so that is the $translate service. This code is placed above the getTourTranslation function.
$rootScope.changeLanguage = function (langKey) {
if(langKey){
if(langKey.length == 2) {
$translate.use(langKey.toLowerCase()+"_"+langKey.toUpperCase());
$rootScope.language = langKey;
} else if(langKey.length == 5) {
$translate.use(langKey);
$rootScope.language = langKey.substring(0,2);
}
}
};
$rootScope.$on('$translateChangeSuccess', function () {
if($translate.use()){
$rootScope.language = $translate.use().substring(0,2);
if($state.$current && !$state.$current.self.abstract) {
$state.reload();
}
}
});
$rootScope.changeLanguage($translate.use());
It is not possible that variable defined on $rootScope is not available withing the same context.
I can imagine only one case:
it calls getTourTranslation so early so none of changeLanguage or $translateChangeSuccess handler ran
The problem was, that $rootScope.language was called before it was initialized.
So, I placed the call to the getTourTranslation() function in an function which is called after firing an button. So, the right variables are now only initialized when they are needed instead of always.
So, I fixed two things, and that all based on the comment from #BotanMan
Since I started to write code with AngularJS, I've been using factories and found them very useful.
I thought that they work like this (pseudo code):
FACTORY NAMESPACE {
PRIVATE FIELDS AND FUNCTIONS
RETURN {
INTERFACES TO ACCESS PRIVATE DATA
}
}
I thought that the expressions in return evaluates only when accessed directly, but, it seems that I didn't get it right.
I understand that the factories and services are very bottom of AngularJS and maybe someone thinks that this question shouldn't be here because it's trivial, and yet...
I created this plunk, I tried to find out why the variable changed inside factory code, won't keep its value after, when being accessed from outside, and what I found out confused me even more, the code inside of every return functions evaluates before anything else and it doesn't get called when it should be (by my logic)! Is. Is that designed that way, and if so, why?
Snippet from plnkr
var myApp = angular.module('app',[])
myApp.factory('_gl', [function () {
// Private fields
var _x;
function _somefunc(){
// This function evaluates even before the code of 'ctrl'
_x = 6;
console.log("changed:"+ _x);
}
return {
x:_x,
changeX:_somefunc()
}
}]);
myApp.controller('ctrl', ['_gl', function (_gl) {
_gl.x=2;
console.log("x init: " + _gl.x);
_gl.changeX(); // This does nothing at all
console.log("x after change: " + _gl.x);
}]);
/* Expected output
x init: 2
changed: 6
x after change:6
/*
/* Actual output
x init: 2
changed:6
x after change: 2
*/
Result:
After all that I found out from #dfsq (that right way is to use getters and setters), I came to the conclusion that although it can make some memory overhead, using simple JS global vars will do for me better.
the code inside of every return functions evaluates before anything else
Of course, because you are executing it with _somefunc().
It should be:
return {
x: _x,
changeX: _somefunc
}
Note, that there should be no () after _somefunc, which is invocation operator. You want changeX to be a reference to _somefunc, not result of _somefunc execution (_somefunc()).
I would like to know what this means:
(function () {
})();
Is this basically saying document.onload?
It’s an Immediately-Invoked Function Expression, or IIFE for short. It executes immediately after it’s created.
It has nothing to do with any event-handler for any events (such as document.onload).
Consider the part within the first pair of parentheses: (function(){})();....it is a regular function expression. Then look at the last pair (function(){})();, this is normally added to an expression to call a function; in this case, our prior expression.
This pattern is often used when trying to avoid polluting the global namespace, because all the variables used inside the IIFE (like in any other normal function) are not visible outside its scope.
This is why, maybe, you confused this construction with an event-handler for window.onload, because it’s often used as this:
(function(){
// all your code here
var foo = function() {};
window.onload = foo;
// ...
})();
// foo is unreachable here (it’s undefined)
Correction suggested by Guffa:
The function is executed right after it's created, not after it is parsed. The entire script block is parsed before any code in it is executed. Also, parsing code doesn't automatically mean that it's executed, if for example the IIFE is inside a function then it won't be executed until the function is called.
Update
Since this is a pretty popular topic, it's worth mentioning that IIFE's can also be written with ES6's arrow function (like Gajus has pointed out in a comment) :
((foo) => {
// do something with foo here foo
})('foo value')
It's just an anonymous function that is executed right after it's created.
It's just as if you assigned it to a variable, and used it right after, only without the variable:
var f = function () {
};
f();
In jQuery there is a similar construct that you might be thinking of:
$(function(){
});
That is the short form of binding the ready event:
$(document).ready(function(){
});
But the above two constructs are not IIFEs.
An immediately-invoked function expression (IIFE) immediately calls a function. This simply means that the function is executed immediately after the completion of the definition.
Three more common wordings:
// Crockford's preference - parens on the inside
(function() {
console.log('Welcome to the Internet. Please follow me.');
}());
//The OPs example, parentheses on the outside
(function() {
console.log('Welcome to the Internet. Please follow me.');
})();
//Using the exclamation mark operator
//https://stackoverflow.com/a/5654929/1175496
!function() {
console.log('Welcome to the Internet. Please follow me.');
}();
If there are no special requirements for its return value, then we can write:
!function(){}(); // => true
~function(){}(); // => -1
+function(){}(); // => NaN
-function(){}(); // => NaN
Alternatively, it can be:
~(function(){})();
void function(){}();
true && function(){ /* code */ }();
15.0, function(){ /* code */ }();
You can even write:
new function(){ /* code */ }
31.new function(){ /* code */ }() //If no parameters, the last () is not required
That construct is called an Immediately Invoked Function Expression (IIFE) which means it gets executed immediately. Think of it as a function getting called automatically when the interpreter reaches that function.
Most Common Use-case:
One of its most common use cases is to limit the scope of a variable made via var. Variables created via var have a scope limited to a function so this construct (which is a function wrapper around certain code) will make sure that your variable scope doesn't leak out of that function.
In following example, count will not be available outside the immediately invoked function i.e. the scope of count will not leak out of the function. You should get a ReferenceError, should you try to access it outside of the immediately invoked function anyway.
(function () {
var count = 10;
})();
console.log(count); // Reference Error: count is not defined
ES6 Alternative (Recommended)
In ES6, we now can have variables created via let and const. Both of them are block-scoped (unlike var which is function-scoped).
Therefore, instead of using that complex construct of IIFE for the use case I mentioned above, you can now write much simpler code to make sure that a variable's scope does not leak out of your desired block.
{
let count = 10;
}
console.log(count); // ReferenceError: count is not defined
In this example, we used let to define count variable which makes count limited to the block of code, we created with the curly brackets {...}.
I call it a “Curly Jail”.
It declares an anonymous function, then calls it:
(function (local_arg) {
// anonymous function
console.log(local_arg);
})(arg);
That is saying execute immediately.
so if I do:
var val = (function(){
var a = 0; // in the scope of this function
return function(x){
a += x;
return a;
};
})();
alert(val(10)); //10
alert(val(11)); //21
Fiddle: http://jsfiddle.net/maniator/LqvpQ/
Second Example:
var val = (function(){
return 13 + 5;
})();
alert(val); //18
(function () {
})();
This is called IIFE (Immediately Invoked Function Expression). One of the famous JavaScript design patterns, it is the heart and soul of the modern day Module pattern. As the name suggests it executes immediately after it is created. This pattern creates an isolated or private scope of execution.
JavaScript prior to ECMAScript 6 used lexical scoping, so IIFE was used for simulating block scoping. (With ECMAScript 6 block scoping is possible with the introduction of the let and const keywords.)
Reference for issue with lexical scoping
Simulate block scoping with IIFE
The performance benefit of using IIFE’s is the ability to pass commonly used global objects like window, document, etc. as an argument by reducing the scope lookup. (Remember JavaScript looks for properties in local scope and way up the chain until global scope). So accessing global objects in local scope reduces the lookup time like below.
(function (globalObj) {
//Access the globalObj
})(window);
This is an Immediately Invoked Function Expression in Javascript:
To understand IIFE in JS, lets break it down:
Expression: Something that returns a value
Example: Try out following in chrome console. These are expressions in JS.
a = 10
output = 10
(1+3)
output = 4
Function Expression:
Example:
// Function Expression
var greet = function(name){
return 'Namaste' + ' ' + name;
}
greet('Santosh');
How function expression works:
- When JS engine runs for the first time (Execution Context - Create Phase), this function (on the right side of = above) does not get executed or stored in the memory. Variable 'greet' is assigned 'undefined' value by the JS engine.
- During execution (Execution Context - Execute phase), the funtion object is created on the fly (its not executed yet), gets assigned to 'greet' variable and it can be invoked using 'greet('somename')'.
3. Immediately Invoked Funtion Expression:
Example:
// IIFE
var greeting = function(name) {
return 'Namaste' + ' ' + name;
}('Santosh')
console.log(greeting) // Namaste Santosh.
How IIFE works:
- Notice the '()' immediately after the function declaration. Every funtion object has a 'CODE' property attached to it which is callable. And we can call it (or invoke it) using '()' braces.
- So here, during the execution (Execution Context - Execute Phase), the function object is created and its executed at the same time
- So now, the greeting variable, instead of having the funtion object, has its return value ( a string )
Typical usecase of IIFE in JS:
The following IIFE pattern is quite commonly used.
// IIFE
// Spelling of Function was not correct , result into error
(function (name) {
var greeting = 'Namaste';
console.log(greeting + ' ' + name);
})('Santosh');
we are doing two things over here.
a) Wrapping our function expression inside braces (). This goes to tell the syntax parser the whatever placed inside the () is an expression (function expression in this case) and is a valid code.
b) We are invoking this funtion at the same time using the () at the end of it.
So this function gets created and executed at the same time (IIFE).
Important usecase for IIFE:
IIFE keeps our code safe.
- IIFE, being a function, has its own execution context, meaning all the variables created inside it are local to this function and are not shared with the global execution context.
Suppose I've another JS file (test1.js) used in my applicaiton along with iife.js (see below).
// test1.js
var greeting = 'Hello';
// iife.js
// Spelling of Function was not correct , result into error
(function (name) {
var greeting = 'Namaste';
console.log(greeting + ' ' + name);
})('Santosh');
console.log(greeting) // No collision happens here. It prints 'Hello'.
So IIFE helps us to write safe code where we are not colliding with the global objects unintentionally.
No, this construct just creates a scope for naming. If you break it in parts you can see that you have an external
(...)();
That is a function invocation. Inside the parenthesis you have:
function() {}
That is an anonymous function. Everything that is declared with var inside the construct will be visible only inside the same construct and will not pollute the global namespace.
That is a self-invoking anonymous function.
Check out the W3Schools explanation of a self-invoking function.
Function expressions can be made "self-invoking".
A self-invoking expression is invoked (started) automatically, without
being called.
Function expressions will execute automatically if the expression is
followed by ().
You cannot self-invoke a function declaration.
This is the self-invoking anonymous function. It is executed while it is defined. Which means this function is defined and invokes itself immediate after the definition.
And the explanation of the syntax is: The function within the first () parenthesis is the function which has no name and by the next (); parenthesis you can understand that it is called at the time it is defined. And you can pass any argument in this second () parenthesis which will be grabbed in the function which is in the first parenthesis. See this example:
(function(obj){
// Do something with this obj
})(object);
Here the 'object' you are passing will be accessible within the function by 'obj', as you are grabbing it in the function signature.
Start here:
var b = 'bee';
console.log(b); // global
Put it in a function and it is no longer global -- your primary goal.
function a() {
var b = 'bee';
console.log(b);
}
a();
console.log(b); // ReferenceError: b is not defined -- *as desired*
Call the function immediately -- oops:
function a() {
var b = 'bee';
console.log(b);
}(); // SyntaxError: Expected () to start arrow function, but got ';' instead of '=>'
Use the parentheses to avoid a syntax error:
(function a() {
var b = 'bee';
console.log(b);
})(); // OK now
You can leave off the function name:
(function () { // no name required
var b = 'bee';
console.log(b);
})();
It doesn't need to be any more complicated than that.
Self-executing functions are typically used to encapsulate context and avoid name collusions. Any variable that you define inside the (function(){..})() are not global.
The code
var same_name = 1;
var myVar = (function() {
var same_name = 2;
console.log(same_name);
})();
console.log(same_name);
produces this output:
2
1
By using this syntax you avoid colliding with global variables declared elsewhere in your JavaScript code.
It is a function expression, it stands for Immediately Invoked Function Expression (IIFE). IIFE is simply a function that is executed right after it is created. So insted of the function having to wait until it is called to be executed, IIFE is executed immediately. Let's construct the IIFE by example. Suppose we have an add function which takes two integers as args and returns the sum
lets make the add function into an IIFE,
Step 1: Define the function
function add (a, b){
return a+b;
}
add(5,5);
Step2: Call the function by wrap the entire functtion declaration into parentheses
(function add (a, b){
return a+b;
})
//add(5,5);
Step 3: To invock the function immediatly just remove the 'add' text from the call.
(function add (a, b){
return a+b;
})(5,5);
The main reason to use an IFFE is to preserve a private scope within your function. Inside your javascript code you want to make sure that, you are not overriding any global variable. Sometimes you may accidentaly define a variable that overrides a global variable. Let's try by example. suppose we have an html file called iffe.html and codes inside body tag are-
<body>
<div id = 'demo'></div>
<script>
document.getElementById("demo").innerHTML = "Hello JavaScript!";
</script>
</body>
Well, above code will execute with out any question, now assume you decleard a variable named document accidentaly or intentional.
<body>
<div id = 'demo'></div>
<script>
document.getElementById("demo").innerHTML = "Hello JavaScript!";
const document = "hi there";
console.log(document);
</script>
</body>
you will endup in a SyntaxError: redeclaration of non-configurable global property document.
But if your desire is to declear a variable name documet you can do it by using IFFE.
<body>
<div id = 'demo'></div>
<script>
(function(){
const document = "hi there";
this.document.getElementById("demo").innerHTML = "Hello JavaScript!";
console.log(document);
})();
document.getElementById("demo").innerHTML = "Hello JavaScript!";
</script>
</body>
Output:
Let's try by an another example, suppose we have an calculator object like bellow-
<body>
<script>
var calculator = {
add:function(a,b){
return a+b;
},
mul:function(a,b){
return a*b;
}
}
console.log(calculator.add(5,10));
</script>
</body>
Well it's working like a charm, what if we accidently re-assigne the value of calculator object.
<body>
<script>
var calculator = {
add:function(a,b){
return a+b;
},
mul:function(a,b){
return a*b;
}
}
console.log(calculator.add(5,10));
calculator = "scientific calculator";
console.log(calculator.mul(5,5));
</script>
</body>
yes you will endup with a TypeError: calculator.mul is not a function iffe.html
But with the help of IFFE we can create a private scope where we can create another variable name calculator and use it;
<body>
<script>
var calculator = {
add:function(a,b){
return a+b;
},
mul:function(a,b){
return a*b;
}
}
var cal = (function(){
var calculator = {
sub:function(a,b){
return a-b;
},
div:function(a,b){
return a/b;
}
}
console.log(this.calculator.mul(5,10));
console.log(calculator.sub(10,5));
return calculator;
})();
console.log(calculator.add(5,10));
console.log(cal.div(10,5));
</script>
</body>
Output:
TL;DR: Expressions can be enclosed in parenthesis, which would conflict with function calling if the expression and block forms of function were combined.
I like counter-examples because they paint a great picture of the logic, and noone else listed any. You might ask, "Why can't the browser see function(){}() and just assume its an expression?" Let's juxtapose the issue with three examples.
var x;
// Here, fibonacci is a block function
function fibonacci(x) {
var value = x < 2 ? x : fibonacci(x-1) + fibonacci(x-2);
if (x === 9) console.log("The " + x + "th fibonacci is: " + value);
return value;
}
(x = 9);
console.log("Value of x: " + x);
console.log("fibonacci is a(n) " + typeof fibonacci);
Observe how things change when we turn the function into an expression.
var x;
// Here, fibonacci is a function expression
(function fibonacci(x) {
var value = x < 2 ? x : fibonacci(x-1) + fibonacci(x-2);
if (x === 9) console.log("The " + x + "th fibonacci is: " + value);
return value;
})
(x = 9);
console.log("Value of x: " + x);
console.log("fibonacci is a(n) " + typeof fibonacci);
The same thing happens when you use the not-operator instead of parenthesis because both operators turn the statement into an expression:
var x;
// Here, fibonacci is a function expression
! function fibonacci(x) {
var value = x < 2 ? x : fibonacci(x-1) + fibonacci(x-2);
if (x === 9) console.log("The " + x + "th fibonacci is: " + value);
return value;
}
(x = 9);
console.log("Value of x: " + x);
console.log("fibonacci is a(n) " + typeof fibonacci);
By turning the function into an expression, it gets executed by the (x = 9) two lines down from it. Thanks to separate behaviors for expression functions and block functions, both examples run fine without ambiguity (specs-wise).
Name Scoping
Another important observation is that named block functions are visible to the entire scope, whereas function expressions are only visible to themselves. In other words, fibonacci is only visible to the last console.log when it is a block in the first example. In all three examples, fibonacci is visible to itself, allowing fibonacci to call itself, which is recursion.
Arrow Functions
Another aspect to the logic is arrow functions. The specs would have had to include arbitrary rules and exceptions for arrow functions if the definitions of block and expression functions were merged together:
function hello() {console.log("Hello World")}
(x) => console.log("hello " + x)
console.log("If you are reading this, no errors occurred");
Although function blocks work fine, function expressions followed by an arrow function produce a syntax error:
! function hello() {console.log("Hello World")}
(x) => console.log("hello " + x)
console.log("If you are reading this, no errors occurred");
Here, it is ambiguous whether the (x) on line two is calling the function on the preceding line or whether it is the function arguments for an arrow function.
Note that arrow functions have been indeed to the ECMAScript standard over the years and were not a factor in the initial design of the language; my point is that a differentiation between expression and block functions helps JavaScript syntax to be a little more logical and coherent.
Self-executing anonymous function. It's executed as soon as it is created.
One short and dummy example where this is useful is:
function prepareList(el){
var list = (function(){
var l = [];
for(var i = 0; i < 9; i++){
l.push(i);
}
return l;
})();
return function (el){
for(var i = 0, l = list.length; i < l; i++){
if(list[i] == el) return list[i];
}
return null;
};
}
var search = prepareList();
search(2);
search(3);
So instead of creating a list each time, you create it only once (less overhead).
It is called IIFE - Immediately Invoked Function Expression. Here is an example to show it's syntax and usage. It is used to scope the use of variables only till the function and not beyond.
(function () {
function Question(q,a,c) {
this.q = q;
this.a = a;
this.c = c;
}
Question.prototype.displayQuestion = function() {
console.log(this.q);
for (var i = 0; i < this.a.length; i++) {
console.log(i+": "+this.a[i]);
}
}
Question.prototype.checkAnswer = function(ans) {
if (ans===this.c) {
console.log("correct");
} else {
console.log("incorrect");
}
}
var q1 = new Question('Is Javascript the coolest?', ['yes', 'no'], 0);
var q2 = new Question('Is python better than Javascript?', ['yes', 'no', 'both are same'], 2);
var q3 = new Question('Is Javascript the worst?', ['yes', 'no'], 1);
var questions = [q1, q2, q3];
var n = Math.floor(Math.random() * questions.length)
var answer = parseInt(prompt(questions[n].displayQuestion()));
questions[n].checkAnswer(answer);
})();
Already many good answers here but here are my 2 cents :p
You can use IIFE (Immediately Invoked Function Expression) for:
Avoiding pollution in the global namespace.
Variables defined in IIFE (or even any normal function) don't overwrite definitions in global scope.
Protecting code from being accessed by outer code.
Everything that you define within the IIFE can be only be accessed within the IIFE. It protects code from being modified by outer code. Only what you explicitly return as the result of function or set as value to outer variables is accessible by outer code.
Avoid naming functions that you don't need to use repeatedly.
Though it's possible to use a named function in IIFE pattern you don't do it as there is no need to call it repeatedly, generally.
For Universal Module Definitions which is used in many JS libraries. Check this question for details.
IIFE is generally used in following fashion :
(function(param){
//code here
})(args);
You can omit the parentheses () around anonymous function and use void operator before anonymous function.
void function(param){
//code here
}(args);
IIFE (Immediately invoked function expression) is a function which executes as soon as the script loads and goes away.
Consider the function below written in a file named iife.js
(function(){
console.log("Hello Stackoverflow!");
})();
This code above will execute as soon as you load iife.js and will print 'Hello Stackoverflow!' on the developer tools' console.
For a Detailed explanation see Immediately-Invoked Function Expression (IIFE)
One more use case is memoization where a cache object is not global:
var calculate = (function() {
var cache = {};
return function(a) {
if (cache[a]) {
return cache[a];
} else {
// Calculate heavy operation
cache[a] = heavyOperation(a);
return cache[a];
}
}
})();
The following code:
(function () {
})();
is called an immediately invoked function expression (IIFE).
It is called a function expression because the ( yourcode ) operator in Javascript force it into an expression. The difference between a function expression and a function declaration is the following:
// declaration:
function declaredFunction () {}
// expressions:
// storing function into variable
const expressedFunction = function () {}
// Using () operator, which transforms the function into an expression
(function () {})
An expression is simply a bunch of code which can be evaluated to a single value. In case of the expressions in the above example this value was a single function object.
After we have an expression which evaluates to a function object we then can immediately invoke the function object with the () operator. For example:
(function() {
const foo = 10; // all variables inside here are scoped to the function block
console.log(foo);
})();
console.log(foo); // referenceError foo is scoped to the IIFE
Why is this useful?
When we are dealing with a large code base and/or when we are importing various libraries the chance of naming conflicts increases. When we are writing certain parts of our code which is related (and thus is using the same variables) inside an IIFE all of the variables and function names are scoped to the function brackets of the IIFE. This reduces chances of naming conflicts and lets you name them more careless (e.g. you don't have to prefix them).
The reason self-evoking anonymous functions are used is they should never be called by other code since they "set up" the code which IS meant to be called (along with giving scope to functions and variables).
In other words, they are like programs that "make classes', at the beginning of program. After they are instantiated (automatically), the only functions that are available are the ones returned in by the anonymous function. However, all the other 'hidden' functions are still there, along with any state (variables set during scope creation).
Very cool.
In ES6 syntax (posting for myself, as I keep landing on this page looking for a quick example):
// simple
const simpleNumber = (() => {
return true ? 1 : 2
})()
// with param
const isPositiveNumber = ((number) => {
return number > 0 ? true : false
})(4)
This function is called self-invoking function. A self-invoking (also called self-executing) function is a nameless (anonymous) function that is invoked(Called) immediately after its definition. Read more here
What these functions do is that when the function is defined, The function is immediately called, which saves time and extra lines of code(as compared to calling it on a seperate line).
Here is an example:
(function() {
var x = 5 + 4;
console.log(x);
})();
An immediately invoked function expression (IIFE) is a function that's executed as soon as it's created. It has no connection with any events or asynchronous execution. You can define an IIFE as shown below:
(function() {
// all your code here
// ...
})();
The first pair of parentheses function(){...} converts the code inside the parentheses into an expression.The second pair of parentheses calls the function resulting from the expression.
An IIFE can also be described as a self-invoking anonymous function. Its most common usage is to limit the scope of a variable made via var or to encapsulate context to avoid name collisions.
This is a more in depth explanation of why you would use this:
"The primary reason to use an IIFE is to obtain data privacy. Because JavaScript's var scopes variables to their containing function, any variables declared within the IIFE cannot be accessed by the outside world."
http://adripofjavascript.com/blog/drips/an-introduction-to-iffes-immediately-invoked-function-expressions.html
Normally, JavaScript code has global scope in the application. When we declare global variable in it, there is a chance for using the same duplicate variable in some other area of the development for some other purpose. Because of this duplication there may happen some error. So we can avoid this global variables by using immediately invoking function expression , this expression is self-executing expression.When we make our code inside this IIFE expression global variable will be like local scope and local variable.
Two ways we can create IIFE
(function () {
"use strict";
var app = angular.module("myModule", []);
}());
OR
(function () {
"use strict";
var app = angular.module("myModule", []);
})();
In the code snippet above, “var app” is a local variable now.
Usually, we don't invoke a function immediately after we write it in the program.
In extremely simple terms, when you call a function right after its creation, it is called IIFE - a fancy name.