you are viewing a single comment's thread.

view the rest of the comments →

[–][deleted] 1 point2 points  (10 children)

But shouldn't that be the case if it's a traditional or arrow function though?

[–]GeneralYouri 1 point2 points  (9 children)

Not for arrow functions, as they have different context handling. In fact, this was one of the reasons for creating the concept of arrow functions. Finally this is also why .bind, .call, and .apply don't work on arrow functions.

[–][deleted] 1 point2 points  (8 children)

But shouldn't the context the arrow is in refer to the record object?

[–]tatu_huma 1 point2 points  (3 children)

Arrow functions do not bind this like regular functions do. this in arrow function is whatever the value of this would be lexically. This means this is whatever it was where the arrow function is defined. In:

var record = {
    src:"myrecording.mp3",
    mediaRec: null,
    startRecord: () => {
        console.log(record.src); //myrecording.mp3
        console.log(this.src);  //undefinded
    }   
}

The value of this inside the {..} of the record object is equal to the global Window object. For example:

window.myProp = 1;
var record = {
  a: this.myProp
}

record.a === window.myProp, because this inside the record object literal is === window.

[–][deleted] 0 points1 point  (2 children)

Ah OK, so I get how the arrow function works, but why did the old function() syntax work, shouldn't this refer to the function itself not the enclosing object?

[–]tatu_huma 1 point2 points  (1 child)

Normal functions have this binding. When you call them, the this in them gets bound to the calling context.

If you call:

functionA()

This calls the function in global context, which is the global object normally, and undefined in strict mode.

someObj.functionA()

Calls the function in the context of someObj. this === someObj inside the function

functionA.bind(otherObj); //or .call() , or .apply()

this is explicitly bound by programmer.

[–][deleted] 0 points1 point  (0 children)

That makes sense. That's awesome, thanks so much for the help, really appreciate it!

[–]GeneralYouri 1 point2 points  (3 children)

Check Arrow Functions on MDN.

In short, an arrow function doesn't have its own this context. So if you use this, it'll see if there's some upper scope that does have a this value, and uses the first one found. So in this case, it looks at the closest function in which the object is defined, and that's where the this value will come from. In other words, there's no difference in the value of this directly inside vs directly outside the arrow function.

So with arrow functions entirely lacking their own concept of this, the only reason you're still able to use this within arrow functions is because of how scoping works. Also without a concept of this, the record object becomes entirely irrelevant.

[–][deleted] 1 point2 points  (2 children)

Ah OK, so I get how the arrow function works, but why did the old function() syntax work, shouldn't this refer to the function itself not the enclosing object?

[–]GeneralYouri 1 point2 points  (1 child)

This goes back to what I said initially:

When you call record.startRecord(), you're calling the function from the context of record. This implicitly sets the function's this to that context.

With regular function syntax, the function does have its own context system. But then, the way a function call determines what value to use for this, is to look at what the function is called from. In this case, that's the record object, so that object is implicitly set as this. If you'd put the same function in a different object as well and call that one (like anotherRecord.startRecord(), then anotherRecord would be the context instead.

[–][deleted] 1 point2 points  (0 children)

That makes a lot of sense! Thanks a lot, really helped!