this in Javascript function
October 03, 2018
In javascript, if a function is a method of an instance or property of an object,
it interprets this
inside the function body as the instance or object itself.
function Factory() {
this.f = function() {
return this
}
}
var k = new Factory()
console.log(k === k.f())
// true
as shown above code sample, this
in the function refers to the instance itself.
Standalone function
"use strict"
function Factory() {
this.f = function() {
function x() {
return this
}
return x()
}
}
var k = new Factory()
console.log(k === k.f(), k.f())
// false undefined
standalone function x
carries its own this
, which is undefined
when running in strict mode nodejs.
Thick arrow function
function Factory() {
this.f = function() {
var x = () => {
return this
}
return x()
}
}
var k = new Factory()
console.log(k === k.f())
// true
Observing above, one can infer that thick arrow functions don’t carry its own this
.
They seek it from execution context, just like other variables.
this
in an object property function
Let’s see sample code first:
var a = {
test: function() {
return this
},
}
console.log(a === a.test()) // true
var b = {}
b.test = a.test
console.log(b === b.test()) // true
this
in an object property function refers to the object itself.
- cf) function bind
var fn = a.test
console.log(a === fn()) // false
var gn = fn.bind(a)
console.log(a === gn()) // true
Apply, Call
function test() {
return this
}
console.log(test()) // undefined
var x = {}
console.log(x === test.apply(x)) // true
console.log(x === test.call(x)) // true
this
in the standalone function test
is given by calling apply, or call with parameter x
.
Runtime environments
In fact, this
seems to have different values in each of the following 4 differnt runtime environments.
- node
- strict mode node
- browser
- strict mode browser
Node
console.log(this); //{}
function test() {
console.log(this === global);
}
test(); //true
new test(); //false
new test()
creates an instance and this
in the test function refers to that instance.
Strict mode node
"use strict";
console.log(this); //{}
function test() {
console.log(this === global);
}
test(); //false
new test(); //false
Browser
console.log(this); //[object Window]
function test() {
console.log(this === window);
}
test(); //true
new test(); //false
Strict mode browser
"use strict";
console.log(this); //undefined
function test() {
console.log(this === window);
}
test(); //false
new test(); //false
Compare thick arrow vs traditional function
Thick arrow function has no special meaning with this
and handles it like any other variables.
The code snippet below run in node. If you want to test it in browser, comment out “use strict”.
"use strict";
var obj = {
test: function() {
return this;
},
task: v => {
if (v) {
this.p = v;
}
return this;
}
};
console.log(obj === obj.test()); //true
console.log(obj === obj.task()); //false
// `this` is object in top level context
console.log(this); //{}
console.log(this === obj.task()); //true
console.log(this === obj.task(3)) //true
console.log(this); //{ p: 3 }
Meanwhile, normal function can be used as an object constructor and has its own this
as a way of reference to the constructed object itself inside the constructor, like so:
var ref;
var o = new function() {
ref = this;
this.x = 1;
}();
console.log(o, ref, o === ref); //{ x: 1 } { x: 1 } true
Written by Sangche. Github