2

I'm doing some practice with javascript data structures and am essentially trying to extend Array.

class Collection {
    constructor(array){
        let collection = Object.create(Array.prototype);

        collection = (Array.apply(collection, array) || collection);

        collection.clear = () => {
            while(this.length > 0){
                this.pop();
            }

            return this
        };

        return(collection);
    }; }

The problem is that when I do the following

c = new Collection([1,2,3]);
c.clear();

c is still [1,2,3] when I am expecting [ ]. Why does modifying this not modify c?

Jonny B
  • 549
  • 1
  • 4
  • 21
  • 1
    Arrow functions do not have their own `this` binding. Instead, `this` refers to the context in which the function was defined. You want to use a regular function, i.e. `collection.clear = function () { ... }`. – Tyler Roper Jun 18 '19 at 18:42
  • 1
    Possible duplicate of [Are 'Arrow Functions' and 'Functions' equivalent / exchangeable?](https://stackoverflow.com/questions/34361379/are-arrow-functions-and-functions-equivalent-exchangeable) – Ivar Jun 18 '19 at 18:44
  • 1
    I personally wouldn't mark this as duplicate. It's solution may be related but the question is because I did not understand there even was a difference. If others have this same issue and don't know about the diff they would never get to that other post. – Jonny B Jun 18 '19 at 18:47
  • Possible duplicate of [How does the "this" keyword work?](https://stackoverflow.com/questions/3127429/how-does-the-this-keyword-work) – Yannick K Jun 18 '19 at 18:48
  • 2
    @JonnyB Duplicates are an effort to consolidate answers into one single place. **Your question is not removed as a result of being marked a duplicate.** Users can still come to this question just as they would any other. The only difference is that it will be suggested they review the other question for answers. – Tyler Roper Jun 18 '19 at 18:48
  • 1
    @TylerRoper, Ohh. I didn't know that. Ok, will mark as duplicate then. Thanks for letting me know that. – Jonny B Jun 18 '19 at 18:50
  • 1
    @JonnyB Not a problem. I've slightly edited my comment for clarity as well. – Tyler Roper Jun 18 '19 at 18:50

2 Answers2

2

Why does modifying this not modify c?

because this references an instance of Collection that you create with new Collection(...), while your constructor returns the value of let collection; which is NOT this in that context.

Besides that, your code is quite interresting. I think this is what you were trying to build:

class Collection extends Array {
  constructor(array) {
    // call the constructor of the Array class
    super(array.length);

    // copy the values from `array` onto `this`;
    Object.assign(this, array);
  }

  clear() {
    // that's all it takes to empty an Array
    this.length = 0;
  }
}


var c = new Collection([1, 2, 3]);
console.log(c);

c.clear();
console.log(c);
Thomas
  • 8,708
  • 1
  • 10
  • 21
  • The article I was using for reference said that simply extending array caused you to lose the bracket function. However, I tested you example and it retained it so I don't know what the article was talking about. It is from 2012 so maybe JS has updated that. https://www.bennadel.com/blog/2292-extending-javascript-arrays-while-keeping-native-bracket-notation-functionality.htm – Jonny B Jun 18 '19 at 19:50
0

This is for the way you defining the function. As you re defining as lamda expression, the value of this is not getting bound properly. Change into to normal function declaration.

class Collection {
    constructor(array){
        let collection = Object.create(Array.prototype);

        collection = (Array.apply(collection, array) || collection);
debugger;
        collection.clear = function()  {
            while(this.length > 0){
                this.pop();
            }

            return this
        };

        return(collection);
    }; }

var c = new Collection([1,2,3]);
c.clear();
console.log(c);
Vishnu
  • 862
  • 6
  • 11