JavaScript 'this'

by LyndseyB

HTML

<input type="button" value=" Click Me " id="btn">

JavaScript

function add(a,b) {
  console.log(this);
	return a + b;   
}

var obj = {
	x: 4,
	add: function(y) {
  console.log(this);
    return this.x + y;
  }
};

var myConstructor = function() {
	this.add = function(a, b) {
  	console.log(this);
  	return a + b;
  };
};

// extending myConstructor prototype
myConstructor.prototype.subtract = function(a,b) {
	console.log(this);
	return a-b;
}

// this overrides the myConstructor __proto__ object
// so calling myConstructory.subtract will throw an error,
// because it no longer exists
myConstructor.prototype = {
	multiply: function(a,b) {
    console.log(this);
  	return a*b;
  }
};



//add(4,5); // add is called whilst in Window scope
//obj.add(5); // add is called from obj scope, so this is obj

//add.apply(obj, [4,5]); // we set this explicitly, this is now obj
//add.call(this, 4, 5); // this is window, we could also use window
const obj2 = {
	name: 'lyndsey',
}

obj.add = obj.add.bind(obj2);
obj.add(5);

//var myConstruct = new myConstructor(); // don't forget the 'new' keyword

//myConstruct.add(4,5); // this refers to myConstruct, which is a reference to myConstructor
//myConstruct.subtract(10,5); // this is still myConstructor because it's called from myConstruct, which is still a reference to myConstructor
//myConstruct.multiply(4,5); // this is myConstruct, still!

var buttonClicker = function() {
	console.log(this);
};

var myBtn = document.querySelector('#btn');

myBtn.addEventListener('click', buttonClicker, false); // buttonClicker is called inside the addEventListener, which is linked to myBtn, therefore this is myBtn or <input type="button" ...>

// .bind() is used to set up the context prior to the function being called, which is different to .call() and .apply() which immediately invoke the function when used.