0

I just wondered why this code run correctly with normal function and resulted in a different result when using arrow function:

the code:

String.prototype.addDotAfter = function() {
  return `${this}.`;
}
let ahmed = 'ahmed';

console.log(ahmed.addDotAfter()) // = ahmed.

the other code that return strange result:

String.prototype.addDotAfter = ()=> {
  return `${this}.`;
}
let ahmed = 'ahmed';

console.log(ahmed.addDotAfter()) // = [object Object].

I don't know why they are different in result!

John Kugelman
  • 349,597
  • 67
  • 533
  • 578
emad
  • 1
  • 1
  • Because arrow functions binds `this`. It is by design. Arrow functions were deliberately designed to be **different** from regular functions and the **only** difference is how it deals with `this`. – slebetman Dec 20 '22 at 02:32
  • @slebetman No, _“arrow functions binds `this`”_ is misleading. The value of `this` immediately inside an arrow function is _the same value_ immediately outside the arrow function; or more concisely: in arrow function bodies, `this` comes from the _lexical scope_ of the arrow function itself. Binding refers to actually receiving an own `this` value. That’s what [`bind`](//developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Function/bind) does; arrow functions ignore binding. – Sebastian Simon Dec 20 '22 at 02:53
  • @SebastianSimon No. The definition of binding in computer science is calculating which object a method operates on. Even in languages that don't normally use the `this` keyword like Java and C++ we call it binding. I'm talking about binding, not the `.bind` method – slebetman Dec 20 '22 at 05:29
  • @slebetman The word “binding” has other semantics in JavaScript, including those that mean the opposite of what arrow functions do. That’s why it’s misleading to refer to this as “binding”. – Sebastian Simon Dec 20 '22 at 09:19
  • @SebastianSimon No. While the word `binding` may have some additional meaning you understand it **also** has the completely ordinary meaning that I'm using: that is the computation of the value of `this`. Your understanding is completely wrong and is contrary to the use of the word `binding` in the ECMAScript spec (currently ECMAScript 2015 6th Edition). When talking about getting the value of the keyword `this` from the lexical environment (what you are saying) the spec says: `supplies the binding of the keyword this`. The ES6 spec uses the word binding the same way I do – slebetman Dec 20 '22 at 16:57
  • .. someone else may have been misleading you to think that `binding` means something different. In which case I stand by my comment in order to educate misinformed people like you. – slebetman Dec 20 '22 at 16:58
  • @SebastianSimon For reference see the spec's use of the word `binding`: https://262.ecma-international.org/6.0/#sec-resolvethisbinding – slebetman Dec 20 '22 at 17:00
  • @slebetman (1/3) _“currently ECMAScript 2015 6th Edition”_ — That’s not the current spec at all; ECMAScript 2022 is the current spec. You can also refer to the [living spec](//tc39.es/ecma262); the abstract operations there are the same as for ECMAScript 2015, though. The abstract operation you linked to (ResolveThisBinding) calls GetThisEnvironment, which calls HasThisBinding on a given environment record first. If HasThisBinding returns **false**, then it checks the outer environment reference, until it reaches the global environment record. – Sebastian Simon Dec 20 '22 at 19:03
  • @slebetman (2/3) The [HasThisBinding](//tc39.es/ecma262/#sec-function-environment-records-hasthisbinding) abstract operation tells you if an environment has a `this` binding or not. Environments with the “lexical” [[ThisBindingStatus]] internal slot _do not_ have a `this` binding (“return **false**”). [BindThisValue](//tc39.es/ecma262/#sec-bindthisvalue) binds the `this` value, first asserting that this internal slot it _not_ “lexical”. – Sebastian Simon Dec 20 '22 at 19:03
  • @slebetman (3/3) [NewFunctionEnvironment](//tc39.es/ecma262/#sec-newfunctionenvironment) sets the [[ThisBindingStatus]] corresponsing to [[ThisMode]], which, in turn, is set from [OrdinaryFunctionCreate](//tc39.es/ecma262/#sec-ordinaryfunctioncreate). Arrow functions are exactly those functions where [[ThisMode]] is set to “lexical”. But this means that HasThisBinding would return **false** for environment records corresponding to arrow functions. This is exactly why I can claim that arrow functions do _not_ bind `this`. – Sebastian Simon Dec 20 '22 at 19:03

0 Answers0