Set "this" variable easily?

65,173

Solution 1

There are two methods defined for all functions in JavaScript, call(), and apply(). The function syntax looks like:

call( /* object */, /* arguments... */ );
apply(/* object */, /* arguments[] */);

What these functions do is call the function they were invoked on, assigning the value of the object parameter to this.

var myFunction = function(){
    alert(this.foo_variable);
}
myFunction.call( document.body );

Solution 2

I think you're looking for call:

myFunction.call(obj, arg1, arg2, ...);

This calls myFunction with this set to obj.

There is also the slightly different method apply, which takes the function parameters as an array:

myFunction.apply(obj, [arg1, arg2, ...]);

Solution 3

If you want to 'store' the this value to a function so that you can call it seamlessly later (e.g. when you don't have access to that value anymore), you can bind it (not available in all browsers though):

var bound = func.bind(someThisValue);

// ... later on, where someThisValue is not available anymore

bound(); // will call with someThisValue as 'this'

Solution 4

My search on how to bind this brought me here so I am posting my findings: In 'ECMAScript 2015' we can also set this lexically using arrow functions to.

See: https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Functions/Arrow_functions

Instead of:

function Person() {
  setInterval(function growUp() {
    // The callback refers to the `self` variable of which
    // the value is the expected object.
    this.age++;
  }.bind(this), 1000);
}

We can now do:

function Person(){
  this.age = 0;

  setInterval(() => {
    this.age++; // |this| properly refers to the person object
  }, 1000);
}

var p = new Person();

Solution 5

Setting the this keyword in javascript.

Javascript has 3 built in methods for setting the this keyword conveniently. They are all located on the Function.prototype object so every function can use them (since every function inherits from this prototype via prototypal inheritance). These functions are the following:

  1. Function.prototype.call(): This function takes the object which you want to use as this as a first argument. Then the remainder of the arguments are the respective arguments of the function which is called.
  2. Function.prototype.apply(): This function takes the object which you want to use as this as a first argument. Then the second argument is an array which contains the values of the arguments of the function which is called (first element of array is first argument of the function, second argument of the array is second argument of function etc.).
  3. Function.prototype.bind(): This function returns a new function which has a different value of this. It takes the object which you want to set as the this value as a first argument and then returns a new function object.

Difference between call/apply and bind:

  • call and apply are similar in the fact that they immediately call the function (with a predefined value of this)
  • bind is different from call and apply in the fact that this function returns a new function with a different binding of the this value.

Examples:

const thisObj = {
  prop1: 1,
  prop2: 2,
};

function myFunc(arg1, arg2) {
  console.log(this.prop1, this.prop2);
  console.log(arg1, arg2);
}

// first arg this obj, other arguments are the  
// respective arguments of the function
myFunc.call(thisObj, 'Call_arg1', 'Call_arg2');

// first arg this obj, other argument is an array which  
// are the respective arguments of the function
myFunc.apply(thisObj, ['Apply_arg1', 'Apply_arg2']);


// the bind method returns a new function with a different
// this context which is stored in the newMyFunc variable
const newMyFunc = myFunc.bind(thisObj);

// now we can call the function like a normal function 
newMyFunc('first', 'second');
Share:
65,173
Erik Philips
Author by

Erik Philips

Highly motivated Programmer who is currently enjoying: .Net 6.x Azure Functions Angular 12 NGXS Entity Framework Linq Typescript Breathing

Updated on July 14, 2022

Comments

  • Erik Philips
    Erik Philips almost 2 years

    I have a pretty good understanding of Javascript, except that I can't figure out a nice way to set the "this" variable. Consider:

    var myFunction = function(){
        alert(this.foo_variable);
    }
    
    var someObj = document.body; //using body as example object
    someObj.foo_variable = "hi"; //set foo_variable so it alerts
    
    var old_fn = someObj.fn;   //store old value
    someObj.fn = myFunction;   //bind to someObj so "this" keyword works
    someObj.fn();              
    someObj.fn = old_fn;       //restore old value
    

    Is there a way to do this without the last 4 lines? It's rather annoying... I've tried binding an anonymous function, which I thought was beautiful and clever, but to no avail:

    var myFunction = function(){
        alert(this.foo_variable);
    }
    
    var someObj = document.body;        //using body as example object
    someObj.foo_variable = "hi";        //set foo_variable so it alerts
    someObj.(function(){ fn(); })();    //fail.
    

    Obviously, passing the variable into myFunction is an option... but that's not the point of this question.

    Thanks.

  • some
    some over 15 years
    See section 15.3.4.3, 15.3.4.4 and 10.1.8 in ECMAScript Language Specification: ecma-international.org/publications/files/ECMA-ST/Ecma-262.p‌​df
  • Adam
    Adam about 10 years
    FYI bind is apparently available in IE9+, FF4+, Safari 5.1.4+ and Chrome 7+ (source). You can also call bind directly on an anonymous function: var myFunction = function(){ /* this = something */ }.bind(something);
  • Trevin Avery
    Trevin Avery over 9 years
    Also, if you're using jQuery, you can use $.proxy(function, element) so that whenever that function is called, it will be in the context of element. api.jquery.com/jquery.proxy
  • Soroush Falahati
    Soroush Falahati almost 6 years
    Another usefull method is .bind()