// collected by Troy Whorten from examples in Cody Lindley article:
// "Fully Understanding the this Keyword" which can be found here:
// http://code.tutsplus.com/tutorials/fully-understanding-the-this-keyword--net-21117
// basic example
function logIt(logString) {
el = document.createElement("span");
console.log(logString);
el.innerHTML = logString;
document.getElementById("log").appendChild(el);
document.getElementById("log").appendChild(document.createElement("br"));
}
function examples() {
var cody = {
living: true,
age: 23,
gender: 'male',
getGender: function () {
return this.gender;
}
};
logIt(cody.getGender()); // logs 'male'
logIt("end basic example");
//change of context example
var foo = 'foo';
var myObject = {
foo: 'I am myObject.foo'
};
var sayFoo = function () {
logIt(this.foo);
};
myObject.sayFoo = sayFoo; //logs "I am myObject.foo"
myObject.sayFoo(); // logs "foo"
sayFoo();
logIt("end context change example");
// nested function example
var myObject = {
func1: function () {
logIt(this); //logs myObject
varfunc2 = function () {
logIt(this); //logs window, and will do so from this point on
varfunc3 = function () {
logIt(this); //logs window, as it’s the head object
}();
}();
}
};
myObject.func1();
logIt("end nested functions example");
//example with passing function as argument
var foo = {
func1: function (bar) {
bar(); //logs window, not foo
logIt(this); //the this keyword here will be a reference to foo object
}
};
foo.func1(function () {
logIt(this);
});
logIt("end function as argument example");
// using variable "that" to keep track of scope
var myObject = {
myProperty: 'Icanseethelight',
myMethod: function () {
var that = this; //store a reference to this (i.e.myObject) in myMethod scope varhelperFunctionfunction(){//childfunction
var helperFunction = function () { //childfunction
//logs 'I can see the light' via scope chain because that=this
logIt(that.myProperty); //logs 'I can see the light'
logIt(this); // logs window object, if we don't use "that"
}();
}
};
myObject.myMethod(); // invoke myMethod
logIt("end 'that' example");
// use call() to set the context for "this"
var myObject = {};
var myFunction = function (param1, param2) {
//setviacall()'this'points to my Object when function is invoked
this.foo = param1;
this.bar = param2;
logIt(this); //logs Object{foo = 'foo', bar = 'bar'}
};
myFunction.call(myObject, 'foo', 'bar'); // invoke function, set this value to myObject
logIt(myObject); // logs Object {foo = 'foo', bar = 'bar'}
logIt("end call() example");
//use apply() to set the context for "this"
var myObject = {};
var myFunction = function (param1, param2) {
//set via apply(), this points to my Object when function is invoked
this.foo = param1;
this.bar = param2;
logIt(this); // logs Object{foo='foo', bar='bar'}
};
myFunction.apply(myObject, ['foo', 'bar']); // invoke function, set this value
logIt(myObject); // logs Object {foo = 'foo', bar = 'bar'}
logIt("end apply() example");
// constructor example
var Person = function (name) {
this.name = name || 'johndoe'; // this will refer to the instanc ecreated
};
var cody = new Person('Cody Lindley'); // create an instance, based on Person constructor
logIt(cody.name); // logs 'Cody Lindley'
// I tried to include the example that doesn't use new, but it blows up JSFiddle, go figure...
//var troy = Person('Troy Whorten'); // notice we didn't use "new"
//console.log(troy.name); // undefined, the value is actually set at window.name
//console.log(window.name); // logs 'Troy Whorten'
logIt("end constructor example");
// protoypeing example
var Person = function (x) {
if (x) {
this.fullName = x
};
};
Person.prototype.whatIsMyFullName = function () {
return this.fullName; // 'this' refers to the instance created from Person()
}
var cody = new Person('cody lindley');
var lisa = new Person('lisa lindley');
// call the inherited whatIsMyFullName method, which uses this to refer to the instance
logIt(cody.whatIsMyFullName(), lisa.whatIsMyFullName());
/* The prototype chain is still in effect, so if the instance does not have a
fullName property, it will look for it in the prototype chain.
Below, we add a fullName property to both the Person prototype and the Object
prototype. See notes. */
Object.prototype.fullName = 'John Doe';
var john = new Person(); // no argument is passed so fullName is not added to instance
logIt(john.whatIsMyFullName()); // logs 'John Doe'
logIt("end prototype example");
logIt("end of examples");
}
<button onclick="examples()">Run Examples</button>
<button onclick='getElementById("log").innerHTML=""'>Clear Log</button>
<br>
<div id="log"></div>