2

My following code is working, but when I use ES6 syntax it is not working anymore. Please explain what is happening?

This code is fully working.

   function Library(){ this.books = [];};
   Library.prototype.addBook = function(book){ 
     this.books.push(book);
   };

   Library.prototype.getBook = function(index){ 
     return this.books[index];
   };

   var m = new Library();
   m.addBook('The Demon Haunted World');       
   m.getBook(0);
   // output will be like 'The Demon Haunted World'

Then I changed the syntax to some extent of ES6. The code then looked like this:

   function Library(){ this.books = [];};
   Library.prototype.addBook = (book) => { 
     this.books.push(book);
   };

   Library.prototype.getBook = (index) => { 
     return this.books[index];
   };

   var m = new Library();
   m.addBook('The Demon Haunted World');

Why is this not working? I'm getting the following error:

    VM505:2 Uncaught TypeError: Cannot read property 'push' of undefined(…)
Reza
  • 2,896
  • 4
  • 26
  • 37
  • 3
    Possible duplicate of [Methods in ES6 objects: using arrow functions](http://stackoverflow.com/questions/31095710/methods-in-es6-objects-using-arrow-functions) – JJJ Oct 27 '16 at 11:10
  • because the this dont represent your object – Beginner Oct 27 '16 at 11:23

1 Answers1

5

the this belongs to window and not the Library constructor. It happens because the arrow function binds the context lexically with the window object or the environment which is parent.

   function Library(){ this.books = [];};
   Library.prototype.addBook = (book) => {
     console.log(this); //window
     this.books.push(book);
   };   

Typically in JS, we have two context/scope [ Global, Function]. In your case the arrow function points to window context or the nearest parent context. which is window.

Thalaivar
  • 23,282
  • 5
  • 60
  • 71
  • 1
    You correctly spotted the problem, but your descriptions are highly inaccurate. References to `arguments`, `super`, `this` and `new.target` in arrow functions always resolve to a binding in a lexically enclosing environment. That's all. No context, no scope, no window. JS has more than two types of scopes btw: At least global, module, function, block and iteration scope. – a better oliver Oct 27 '16 at 12:21
  • 2
    ES6 has... ES5, its only function/global... may be using eval you can create dynamic context and also try/catch has its own scope... – Thalaivar Oct 27 '16 at 12:31