1

function Dog(name, age) {
  this.name = name;
  this.age = age;
  this.bark = function() {
    this.name += " hello";
    console.log(this.name);
    (function() {
      this.name += "a";
      console.log(this.name);
    })();
  }
};
let dog = new Dog("tep", 2);
dog.bark();

can anyone please tell me what happened here? when I open the console, It print 2 lines which are

  • tep hello
  • a

every time I reload the page, it continue add the 'a' in line 2, and I saw in the window object, there is property "name"

  • tep hello
  • aa
TessavWalstijn
  • 1,204
  • 15
  • 27
longbui
  • 13
  • 2
  • 1
    Since it's 2020 why not use `class` instead of the old-school `function`-as-Object style? – tadman Nov 06 '20 at 08:15
  • 1
    Hint: What scope does your inner anonymous function run in when called? – tadman Nov 06 '20 at 08:16
  • 1
    You can fix this by using an [arrow function](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/Arrow_functions) which preserves `this` binding. – tadman Nov 06 '20 at 08:17
  • I'm new and i'm reading the headfirst javascript :)) – longbui Nov 06 '20 at 08:20
  • 2
    The 2014 version? If so, that book is no longer relevant and isn't worth using. ES6 has dramatically changed how JavaScript works and how it *should* be used. The MDN site has some [fantastic resources](https://developer.mozilla.org/en-US/docs/Learn/JavaScript) on learning JavaScript that should be your first stop. For any other references, be *sure* that they cover ES6 properly, and it's not just some additional chapter at the end that hand-waves over it. – tadman Nov 06 '20 at 08:21
  • Make sure to use strict mode and get the relevant exception – Bergi Nov 06 '20 at 08:23
  • thank you sir! i'm trying to understand the es5 and how it differs from ES6 – longbui Nov 06 '20 at 08:33

1 Answers1

0

Inside an anonymous function you lose the this binding, so it just defaults to something. In a browser it's effectively window.

To fix this you can use an arrow function as those preserve this bindings:

 (() => {
    this.name += "a";
    console.log(this.name);
 })();

Creating these sorts of closure-functions is not something you want to do without an exceptionally good reason, though. They're normally used to ensure variables don't "escape", but with the introduction of let and const it's far less likely you'll have to use one.

In this case there's absolutely no advantage to using one, you're not making any locals anyway.

tadman
  • 194,930
  • 21
  • 217
  • 240