From MDN: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/this, it says:
In strict mode, however, the value of this remains at whatever it was set to when entering the execution context, so, in the following case, this will default to undefined:
function f2() {
'use strict'; // see strict mode
return this;
}
f2() === undefined; // true
This suggests that if I (1) 'use strict'; and (2) define f2 inside another function that invoking f2 would bind the outside function's this for f2. BUT!
It doesn't work...
'use strict';
function AlarmClock(clockName) {
this.clockName=clockName;
}
console.log("hello, let's see some weird stuff");
console.log("THIS in global", this);
AlarmClock.prototype.start = function(seconds) {
console.log('outer', this);
var testInside = function() {
console.log('inner', this);
}
testInside();
}
var clock = new AlarmClock("Horizons")
clock.start(1);
// WITHOUT CONSTRUCTORS
function withoutOut() {
console.log("withoutOut", this)
this.howard="notSoBad";
console.log("modifiedTheThis, should have Howard", this)
function withoutIn1() {
console.log("withoutIn1", this);
console.log("Strict should set to the defining object's this");
}
var withoutIn2 = function() {
console.log("withoutIn2", this);
console.log("Strict should set to the defining object's this");
}
withoutIn1();
withoutIn2();
}
withoutOut.bind({Moose: "genius"})();
console.log("DONE");
Gives this output:
hello, let's see some weird stuff
THIS in global {}
outer AlarmClock { clockName: 'Horizons' }
inner undefined
withoutOut { Moose: 'genius' }
modifiedTheThis, should have Howard { Moose: 'genius', howard: 'notSoBad' }
withoutIn1 undefined
Strict should set to the defining object's this
withoutIn2 undefined
Strict should set to the defining object's this
DONE
NOTE: I ran this with node v10.5.0, from a mac osx command line.
NOTE2: If you run in devtools, you have to follow these steps for use strict.
NOTE3: Basically, I want to find someway to get inner, withoutIn1 or withoutIn2 to NOT be undefined. And, I know you can do this with an explicit bind, but I want to specifically get the behavior specified in the MDN doc.
If you agree with me, MDN should change the "this" doc to just say, in function context with "use strict", this is set to undefined ALWAYS. (author likes)
Or, Chrome should change the implementation. (author dislikes)
The value of this
when a function is called has nothing at all to do with how or where the function is defined. It has to do only with how the function is called. Calling your inner functions:
AlarmClock.prototype.start = function(seconds) {
console.log('outer', this);
var testInside = function() {
console.log('inner', this);
}
testInside();
}
like testInside()
without any object reference means that there's nothing to bind to this
, and in strict mode that means this
is undefined
. However, if you had written instead
testInside.call(this);
then there'd be a context value. The fact that a function is "inside" another function, again, has absolutely no impact on how this
is bound. Alternatively:
this.testInside = testInside;
this.testInside();
it'd also work, because once again there's a context.
Oh, and also also, the new(ish) arrow function mechanism does let you create functions that effectively "inherit" the this
value from their lexical environment. So:
AlarmClock.prototype.start = function(seconds) {
console.log('outer', this);
var testInside = () => {
console.log('inner', this);
}
testInside();
}
would work, because calling an arrow function does not involve any this
binding; this
behaves essentially like a variable in the closure.