Javascript function stored in array vs in a variable - javascript

In this example why does pushing the function reference onto the array not change the scope execution context of this whereas assigning the function reference to a new variable does change the scope execution context of this?
(function() {
function Car(year) {
this.year = year;
}
Car.prototype = {
logYear: function() {
console.log(this.year);
}
};
var ford = new Car('Ford', 1999);
ford.logYear();
var cbs = [];
cbs.push(ford.logYear);
for(var x = 0; x < cbs.length; x++) {
cbs[x](); // -> 1999 #1
var callback = cbs[x];
callback(); // -> undefined #2
}
})()
Is this because the reference to the function in the array points to the original function on the ford object where this is still defined as the instance (#1) and the variable assignment changes the this to point to the wrapping IIFE block (#2)?
Is this a good pattern if I need to collect of bunch of methods like this from various objects and call them somewhere else?
How does this referential calling relate to examples like console.error.bind(console)?
Thanks!
-- Update
Thanks to #Satyajeet for the nice explanation and clarification.
Typos & copying errors aside the reason I was asking this question in the first place is that I suspected what Satyajeet confirmed but an application I am working on does not reflect this behavior (or so I thought).
It turns out that in the application I am performing a similar process to the above code where I call cbs.push(ford.logYear);, adding multiple methods from different objects to an array.
At a point in the app I call all these methods and expect them to behave in the same way as when they are called in the execution context scope of the original object... and they do, because the values the methods interact with are not attached to this, they are captured in closures.
See example plunker here
-- Update 2
Fixed usage of execution context and scope to be accurate for each part of the question/answer.

Ignoring your late night copy paste mistake, and redefining your Car function to
function Car(name, year) {
this.name = name;
this.year = year
}
#1 indeed more of a question about how Array works rather then about the context and scope(*#2)
You are calling a function inside an array, So in javascript each element of an array is a property of that Array Object. for example
var a = [];
a.push('Some value'); // a.0 is a property
but you just can not call a.0 because in javascript properties that begin with a digit cannot be referenced with dot notation, and must be accessed using bracket notation
So when you are calling cbx[0]() it is essentially same as cbx.0().
And here comes the role of Scope and Execution context in javascript. There are already many good articles and answers about Scope and Context in javascript. Just like this, So i think its not worth to explain all that here.
But fundamentally this is not defined till the execution of function(this depends on Execution context rather then scope).
So your #1 will print undefined because cbs[0]() is equivalent to cbs.0(), And this(Execution context) is set to Array itself, which is [function]. (You only have a function inside it).
And your #2 will also print undefined because Execution context is global(window object in case of browser) there.
Answer to your 3rd question is, You need to Explicitly hard bind Execution context to your function.
cbs.push(ford.logYear.bind(ford));
And your 4th question is i think just an another use case of ES5's bind method, Nothing special. It is normally used because browser implementations requires that execution context(this) of console.error must be set to window.console.

Related

Javascript: Create a sub-class within a class [duplicate]

I thought I had a reasonable understanding of the this object in JavaScript. When dealing with objects, callbacks, and both events and handlers, I haven't had a problem with it since time immemorial. Now, however, all has changed.
I've fallen head over heels in love with JavaScript. Pure JS, that is, not jQuery, prototype.js, dojo... So naturally, I've taken to using closures. In some cases, though, this is catching me off guard here. Take this snippet for one:
function anyFunc(par)
{
//console.log(par);
console.log(this);
}
function makeClosure(func)
{
return function(par)
{
return func(par);
}
}
var close = makeClosure(anyFunc);
close('Foo');
var objWithClosure = {cls:makeClosure(anyFunc),prop:'foobar'};
objWithClosure.cls(objWithClosure.prop);
var scndObj = {prop:'Foobar2'};
scndObj.cls = makeClosure;
scndObj.cls = scndObj.cls(anyFunc);
scndObj.cls(scndObj.prop);
In all three cases, this logs as the window object. It's an easy fix, of course:
function makeClosure(func)
{
return function(par)
{
return func.call(this,par);
}
}
This fix works, I put it here to avoid people answering this, without explaining what I need to know: why is this behaving the way it does here?
ensures the caller is effectively the object that the closure belongs to. What I fail to understand is this:
Sure enough, this points to the window object in the first case, but in other cases, it shouldn't. I tried logging this in the makeClosure function just before returning, and it did log the object itself, not the window object. But when the actual closure is used, this is back to pointing to the window object. Why?
The only thing I can think of is that, by passing the anyFunc function as an argument, I'm actually passing window.anyFunc. So I tried this quick fix:
function makeClosure(func)
{
var theFunc = func;
return function(par)
{
theFunc(par);
}
}
With the expected results, this now points to the objects, but again: Why? I have a few idea's (theFunc is a reference to the function in the local scope [this > private: theFunc]?), but I'm sure there are people here with a lot more know-how when it comes to JS, so I was hoping to get some more explanation or links to articles worth reading from them...
Thanks
Update
Here's a fiddle, may be I left something out, but here this logs all sorts of things ;)
Edit/Update 2
The case that confuses me is here.
Final Edit
Ok, This is getting a rather messy post. So to clarify: What I was expecting was a behaviour similar to this:
function makeClosure()
{
function fromThisFunc()
{
console.log(this);
}
return fromThisFunc;
}
var windowContext = makeClosure();
windowContext();
var objectContext = {cls:makeClosure()};
objectContext.cls();
What caught me, was that the function anyFunc wasn't declared within the correct scope, and therefore, this pointed to the window object. I found this out by reading an ancient scroll I found somewhere on the web.
But something a little more complicated has happened because the function object now referred to by globalVar was created with a [[scope]] property referring to a scope chain containing the Activation/Variable object belonging to the execution context in which it was created (and the global object). Now the Activation/Variable object cannot be garbage collected either as the execution of the function object referred to by globalVar will need to add the whole scope chain from its [[scope]] property to the scope of the execution context created for each call to it.
So what I needed to do, was simplify rather then complicate things:
function fromThisFunc()
{
console.log(this);
}
function makeClosure(funcRef)
{
//some code here
return funcRef;
}
That should work, right?
PS: I'll except Alnitak's answer, but special thanks goes to Felix Kling for all the patience and info.
As soon as you call:
return func(par);
You're creating a new scope (with its own this) and in this case because you haven't specified an object, this === window usually or undefined in strict mode. The called function does not inherit whatever this was in the calling scope.
Ways to set a value for this are:
myobj.func(par); // this === myobj
or
func.call(myobj, ...) // this === myobj
There are also:
apply
bind
arrow functions, where this is set to the same value as the outer execution context (also see MDN:Arrow functions )
The value of this depends only on whether you call the function as a method or as a function.
If you call it as a method, this will be the object that the method belongs to:
obj.myFunction();
If you call it as a function, this will be the window object:
myFunction();
Note that even if you are in a method that belongs to an object, you still have to call other methods in the object using the method syntax, otherwise they will be called as functions:
this.myOtherFunction();
If you put a method reference in a variable, you will detach it from the object, and it will be called as a function:
var f = obj.myFunction;
f();
The call and apply methods are used to call a function as a method even if it's not a method in the object (or if it's a method in a different object):
myFunction.call(obj);

Can you get the property name through which a function was called?

I've done a lot of searching and some playing around, and I'm pretty sure the answer to this question is no, but I'm hoping a JavaScript expert might have a trick up his sleeve that can do this.
A JavaScript function can be referenced by multiple properties, even on completely different objects, so there's no such thing as the object or property that holds the function. But any time you actually call a function, you must have done so via a single object (at the very least, the window object for global function calls) and property on that object.
(A function can also be called via a function-local variable, but we can consider the function-local variable to be a property of the activation object of the scope, so that case is not an exception to this rule.)
My question is, is there a way to get that property name that was used to call the function, from inside the function body? I don't want to pass in the property name as an argument, or closure around a variable in an enclosing scope, or store the name as a separate property on the object that holds the function reference and have the function access that name property on the this object.
Here's an example of what I want to do:
var callName1 = function() { var callName = /* some magic */; alert(callName); };
var obj1 = {'callName2':callName1, 'callName3':callName1 };
var obj2 = {'callName4':callName1, 'callName5':callName1 };
callName1(); // should alert 'callName1'
obj1.callName2(); // should alert 'callName2'
obj1.callName3(); // should alert 'callName3'
obj2.callName4(); // should alert 'callName4'
obj2.callName5(); // should alert 'callName5'
From my searching, it looks like the closest you can get to the above is arguments.callee.name, but that won't work, because that only returns the name that was fixed to the function object when it was defined, and only if it was defined as a named function (which the function in my example is not).
I also considered that maybe you could iterate over all properties of the this object and test for equality with arguments.callee to find the property whose value is a reference to the function itself, but that won't work either (in the general case), because there could be multiple references to the function in the object's own (or inherited) property set, as in my example. (Also, that seems like it would be kind of an inefficient solution.)
Can this be done?
Short answer:
No, you cannot get "the property name" used to call your function.
There may be no name at all, or multiple names across different scopes, so "the property name" is pretty ill defined.
arguments.callee is deprecated and should not be used.
There exists no solution that does not use arguments or closure.
Long answer:
As thefourtheye commented, you should rethink what you are trying to do and ask that instead in a new question. But there are some common misconceptions, so I will try to explain why you cannot get the "simple property name".
The reason is because it is not simple.
Before we go ahead, let us clarify something. Activation Objects are not objects at all.
The ECMAScript 5.1 specification calls them Environment Records (10.2.1), but a more common term is Scope chain.
In a browser the global scope is (often) the window object, but all other scopes are not objects.
There may be an object that you use to call a function, and when you call a function you must be in some scope.
With few exceptions, scopes are not objects, and objects are not scopes.
Then, there are many names.
When you call a function, you need to reference it, such as through an object property. This reference may have a name.
Scope chain has declarations, which always have a name.
A Function (the real function, not reference) may also have a function name - your arguments.callee.name - which is fixed at declaration.
Not only are they different names, they are not (always) the "the property name" you are seeking.
var obj = { prop : function f(){} }, func = obj.prop;
// "obj" and "func" are declarations.
// Function name is "f" - use this name instead of arguments.callee
// Property name is "prop"
func(); // Reference name is "func"
obj.prop(); // Reference names are "obj" and "prop"
// But they are the same function!
// P.S. "this" in f is undefined (strict mode) or window (non-strict)
So, a function reference may comes from a binding (e.g. function declaration), an Object (arguments.callee), or a variable.
They are all References (8.7). And reference does have a name (so to speak).
The catch is, a function reference does not always come from an object or the scope chain, and its name is not always defined.
For example a common closure technique:
(function(i){ /* what is my name? */ })(i)
Even if the reference does have a name, a function call (11.2.3) does not pass the reference or its name to the function in any way.
Which keeps the JavaScript engine sane. Consider this example:
eval("(new Function('return function a(){}'))()")() // Calls function 'a'.
The final function call refers the eval function, which refers the result of a new global scope (in strict mode, anyway), which refers a function call statement, which refers a group, which refers an anonymous Function object, and which contains code that expresses and returns a function called 'a'.
If you want to get the "property name" from within a, which one should it get? "eval"? "Function"? "anonymous"? "a"? All of them?
Before you answer, consider complications such as function access across iframes, which has different globals as well as cross origin restriction, or interaction with native functions (Function.prototype.bind for example), and you will see how it quickly becomes hell.
This is also why arguments.caller, __caller__, and other similar techniques are now all deprecated.
The "property name" of a function is even more ill defined than the caller, almost unrealistic.
At least caller is always an execution context (not necessary a function).
So, not knowing what your real problem is, the best bet of getting the "property name" is using closure.
there is no reflection, but you can use function behavior to make adding your own fairly painless, and without resorting to try/catch, arguments.callee, Function.caller, or other strongly frowned-upon behavior, just wasteful looping:
// returning a function from inside a function always creates a new, unique function we can self-identify later:
function callName() {
return function callMe(){
for(var it in this) if(this[it]===callMe) return alert(it);
}
};
//the one ugly about this is the extra "()" at the end:
var obj1 = {'callName2':callName(), 'callName3':callName() };
var obj2 = {'callName4':callName(), 'callName5':callName() };
//test out the tattle-tale function:
obj1.callName2(); // alerts 'callName2'
obj2.callName5(); // alerts 'callName5'
if you REALLY want to make it look like an assignment and avoid the execution parens each time in the object literal, you can do this hacky routine to create an invoking alias:
function callName() {
return function callMe(){
for(var it in this) if(this[it]===callMe) return alert(it);
}
};
//make an alias to execute a function each time it's used :
Object.defineProperty(window, 'callNamer', {get: function(){ return callName() }});
//use the alias to assign a tattle-tale function (look ma, no parens!):
var obj1 = {'callName2': callNamer, 'callName3': callNamer };
var obj2 = {'callName4': callNamer, 'callName5': callNamer };
//try it out:
obj1.callName2(); // alerts 'callName2'
obj2.callName5(); // alerts 'callName5'
all that aside, you can probably accomplish what you need to do without all the looping required by this approach.
Advantages:
works on globals or object properties
requires no repetitive key/name passing
uses no proprietary or deprecated features
does not use arguments or closure
surrounding code executes faster (optimized) than
a try/catch version
is not confused by repeated uses
can handle new and deleted (renamed) properties
Caveats:
doesn't work on private vars, which have no property name
partially loops owner object each access
slower computation than a memorized property or code-time repetition
won't survive call/bind/apply
wont survive a setTimeout without bind() or a wrapper function
cannot easily be cloned
honestly, i think all the ways of accomplishing this task are "less than ideal", to be polite, and i would recommend you just bite the coding bullet and pass extra key names, or automate that by using a method to add properties to a blank object instead of coding it all in an object literal.
Yes.
Sort Of.
It depends on the browser. (Chrome=OK, Firefox=Nope)
You can use a factory to create the function, and a call stack parsing hack that will probably get me arrested.
This solution works in my version of Chrome on Windows 7, but the approach could be adapted to other browsers (if they support stack and show the property name in the call stack like Chrome does). I would not recommend doing this in production code as it is a pretty brittle hack; instead improve the architecture of your program so that you do not need to rely on knowing the name of the calling property. You didn't post details about your problem domain so this is just a fun little thought experiment; to wit:
JSFiddle demo: http://jsfiddle.net/tv9m36fr/
Runnable snippet: (scroll down and click Run code snippet)
function getCallerName(ex) {
// parse the call stack to find name of caller; assumes called from object property
// todo: replace with regex (left as exercise for the reader)
// this works in chrome on win7. other browsers may format differently(?) but not tested.
// easy enough to extend this concept to be browser-specific if rules are known.
// this is only for educational purposes; I would not do this in production code.
var stack = ex.stack.toString();
var idx = stack.indexOf('\n');
var lines = ex.stack.substring(idx + 1);
var objectSentinel = 'Object.';
idx = lines.indexOf(objectSentinel);
var line = lines.substring(idx + objectSentinel.length);
idx = line.indexOf(' ');
var callerName = line.substring(0, idx);
return callerName;
}
var Factory = {
getFunction: function () {
return function () {
var callName = "";
try {
throw up; // you don't *have* to throw to get stack trace, but it's more fun!
} catch (ex) {
callName = getCallerName(ex);
}
alert(callName);
};
}
}
var obj1 = {
'callName2': Factory.getFunction(),
'callName3': Factory.getFunction()
};
var obj2 = {
'callName4': Factory.getFunction(),
'callName5': Factory.getFunction()
};
obj1.callName2(); // should alert 'callName2'
obj1.callName3(); // should alert 'callName3'
obj2.callName4(); // should alert 'callName4'
obj2.callName5(); // should alert 'callName5'

Javascript closure & "that" instead of "this" in a specific example

I know this subject had been dealt a lot here, but I saw this specific example on the Pluralsight JS design pattern course, and I'll be glad for your help understanding the closure there.
This is the example:
var Calc = function(start) {
var that = this;
this.add = function(x) {
start = start + x;
return that;
};
this.multiply = function(x) {
start = start * x;
return that;
};
this.equals = function(callback) {
callback(start);
return that;
};
}
new Calc(0)
.add(1)
.add(2)
.multiply(3)
.equals(function(result){
console.log(result); // returns 9
});
Here's the JSFiddle link: http://jsfiddle.net/3yJ8Y/5/
I'll be VERY glad for:
Understanding the "that" use. Why do we need it in this specific
example? it does the same with "this". Can you pls give examples and explain when do we need to do "var that = this"?
Understanding this way of creating functions from an object. why do we have to use "this" and then .functionName? like this.add = ...
A detailed and extensive explanation for this very specific closure example.
Thank you so much!
start becomes a global variable of the Calc object
Each method of the Calc object (add, multiple, equals) references that same global variable
new Calc(0) // <- sets start to 0
.add(1) // calls add() <- sets start to 1
.add(2) // calls add() <- sets start to 3
.multiply(3) // calls multiple() <- sets start to 9
.equals(function(result){
console.log(result); // returns 9
});
Thanks to #elclanrs for reminding me of things I had internalized and forgotten...
That
The important thing here is that that... is unnecessary.
I'll quote an article that #elclanrs linked in his comment on the above post:
Scope In Javascript
JavaScript establishes an execution context for the function call, setting this to the object referenced by whatever came before the last ”.”
Because each method is called with the outer Calc before it's dot, the this value inside that method is assigned as the outer object.
The outer object, in turn, is its own brand new, self-contained scope because it was created with the new keyword:
When new[Calc]() is executed, a completely new object is created transparently in the background. [Calc] is called, and its this keyword is set to reference that new object.
(Scope in Javascript, again, with my edits in brackets).
Now you might be wondering, "How is this:
.add(1)
.add(2)
.multiply(3)
... keeping the right scope? You said that whatever is before the . is passed in as the this variable in this situation!?"
Absolutely true, and in this situation, each method is returning this, which allows method chaining. (They're actually returning that, but we already determined that was an unnecessary variable in this context).
Why use that
First of all, let me say I prefer var self = this over var that = this but there are arguments either way.
Let's arbitrarily modify the object to have a method that looks like this:
this.getInternalThis = function(){
var internalThis = function(){
console.log( this );
}
}
First of all, let's get this out of the way: this example is stupid, but you'll see things like this - a function defined in other scopes - all the time.
Here are the important things to notice:
It's called by name, and nothing more (no prefixed . notation, for example)
... that's it!
When a function is called this way, the engine has to figure out something to assign this as in the scope of the function. It defaults to window.
If you were to run this code, you would get Window in the console.
Now, what if we wanted this inside that internal function call to be the calling value of this?
This situation is where you need a that variable. We can modify the function to look like:
this.getInternalThis = function(){
var that = this,
internalThis = function(){
console.log( that );
};
}
Now when you run this method, you get the value of the calling object in the console.
In my case it was Object { add=function(), multiply=function(), equals=function(), getInternalThis=function()}.
Sometimes, that's what you need or expect, so that's why you would use a var that = this declaration.
Using this. to define a method
As I mentioned earlier:
Because each method is called with the outer Calc before it's dot, the this value inside that method is assigned as the outer object.
Remember that this in the scope of Calc() is a reference to the new Calc object, so each method is being given the Calc object as the value of this (remember, it's before the .!) when they enter their new scope from that context.
Hopefully this gives you a little info on how JavaScript scopes and the assignment of this works.

Javascript "saves" function data in memory?

Example :
var myFunctArray=new Array();
for(var i=0; i<10; i++) {
addValues(i);
}
function addValues(myPoint)
{
myFunct=function () {
var myVar="Line " + myPoint;
console.log(myVar);
}
myFunctArray.push(myFunct);
}
myFunctArray[3]();
when I call the 4° function, how can it remembers the value of myPoint? In fact it is Line 3 the output, so myPoint value must be "stored" somewhere, for each function.
So, it stores 10 "definitions" of myFunct in the stack memory?
Hope it is clear what I mean.
It's called a closure. Any variables that are currently in scope when you create a new function are associated with that closure.
So, it stores 10 "definitions" of myFunct in the stack memory?
Yes, it does.
Your array contains ten closures, each of which has captured its own version of myPoint.
Thiefmaster answered your question pretty much. Yes, this code will use more and more memory, depending on how many closures your array contains. It has to be said that most modern engines will assign a reference to the function assigned to the MyFunct variable and a specific "call object" that contains the closure vars. In other words, your array will look something along the lines of:
myFuncArray[0] = {call:
{myPoint:'Whatever value was passed to the addValues function the first time'},
valueOf: myFunct};
//the actual value is a reference to myFunct
//JS provides an implicit link to the call property, which is bound to this particular reference
myFuncArray[1] = {call:
{myPoint:'The value passed to addValues the second time'},
valueOf: myFunct};
You don't have access to the object as such, but this is just the way to think of how JS will keep things organized in memory.
Slightly off topic, but you're creating an implied global with your MyFunct variable:
function addValues(myPoint)
{
var anotherClosureVar = 'This will be accessible, too: it\'s part of the closure';
var myFunct = function()
{//use var to declare in addValues scope, instead of using an implied global
var myVar="Line " + myPoint;
console.log(myVar);
console.log(anotherClosureVar);//will work, too
};
myFunctArray.push(myFunct);
}
All in all, if this is your code, memory shouldn't be that big of an issue. Even if this code were to run on an old JScript engine, it'll take some time before you've used up a meaningful amount of memory. Still, it's a good habit to think about stuff like this, and I do hope I made sense here, I'm not a native speaker, which makes explaining the more abstract aspects of JS somewhat tricky

JavaScript closure and the this object

I thought I had a reasonable understanding of the this object in JavaScript. When dealing with objects, callbacks, and both events and handlers, I haven't had a problem with it since time immemorial. Now, however, all has changed.
I've fallen head over heels in love with JavaScript. Pure JS, that is, not jQuery, prototype.js, dojo... So naturally, I've taken to using closures. In some cases, though, this is catching me off guard here. Take this snippet for one:
function anyFunc(par)
{
//console.log(par);
console.log(this);
}
function makeClosure(func)
{
return function(par)
{
return func(par);
}
}
var close = makeClosure(anyFunc);
close('Foo');
var objWithClosure = {cls:makeClosure(anyFunc),prop:'foobar'};
objWithClosure.cls(objWithClosure.prop);
var scndObj = {prop:'Foobar2'};
scndObj.cls = makeClosure;
scndObj.cls = scndObj.cls(anyFunc);
scndObj.cls(scndObj.prop);
In all three cases, this logs as the window object. It's an easy fix, of course:
function makeClosure(func)
{
return function(par)
{
return func.call(this,par);
}
}
This fix works, I put it here to avoid people answering this, without explaining what I need to know: why is this behaving the way it does here?
ensures the caller is effectively the object that the closure belongs to. What I fail to understand is this:
Sure enough, this points to the window object in the first case, but in other cases, it shouldn't. I tried logging this in the makeClosure function just before returning, and it did log the object itself, not the window object. But when the actual closure is used, this is back to pointing to the window object. Why?
The only thing I can think of is that, by passing the anyFunc function as an argument, I'm actually passing window.anyFunc. So I tried this quick fix:
function makeClosure(func)
{
var theFunc = func;
return function(par)
{
theFunc(par);
}
}
With the expected results, this now points to the objects, but again: Why? I have a few idea's (theFunc is a reference to the function in the local scope [this > private: theFunc]?), but I'm sure there are people here with a lot more know-how when it comes to JS, so I was hoping to get some more explanation or links to articles worth reading from them...
Thanks
Update
Here's a fiddle, may be I left something out, but here this logs all sorts of things ;)
Edit/Update 2
The case that confuses me is here.
Final Edit
Ok, This is getting a rather messy post. So to clarify: What I was expecting was a behaviour similar to this:
function makeClosure()
{
function fromThisFunc()
{
console.log(this);
}
return fromThisFunc;
}
var windowContext = makeClosure();
windowContext();
var objectContext = {cls:makeClosure()};
objectContext.cls();
What caught me, was that the function anyFunc wasn't declared within the correct scope, and therefore, this pointed to the window object. I found this out by reading an ancient scroll I found somewhere on the web.
But something a little more complicated has happened because the function object now referred to by globalVar was created with a [[scope]] property referring to a scope chain containing the Activation/Variable object belonging to the execution context in which it was created (and the global object). Now the Activation/Variable object cannot be garbage collected either as the execution of the function object referred to by globalVar will need to add the whole scope chain from its [[scope]] property to the scope of the execution context created for each call to it.
So what I needed to do, was simplify rather then complicate things:
function fromThisFunc()
{
console.log(this);
}
function makeClosure(funcRef)
{
//some code here
return funcRef;
}
That should work, right?
PS: I'll except Alnitak's answer, but special thanks goes to Felix Kling for all the patience and info.
As soon as you call:
return func(par);
You're creating a new scope (with its own this) and in this case because you haven't specified an object, this === window usually or undefined in strict mode. The called function does not inherit whatever this was in the calling scope.
Ways to set a value for this are:
myobj.func(par); // this === myobj
or
func.call(myobj, ...) // this === myobj
There are also:
apply
bind
arrow functions, where this is set to the same value as the outer execution context (also see MDN:Arrow functions )
The value of this depends only on whether you call the function as a method or as a function.
If you call it as a method, this will be the object that the method belongs to:
obj.myFunction();
If you call it as a function, this will be the window object:
myFunction();
Note that even if you are in a method that belongs to an object, you still have to call other methods in the object using the method syntax, otherwise they will be called as functions:
this.myOtherFunction();
If you put a method reference in a variable, you will detach it from the object, and it will be called as a function:
var f = obj.myFunction;
f();
The call and apply methods are used to call a function as a method even if it's not a method in the object (or if it's a method in a different object):
myFunction.call(obj);

Categories

Resources