Stack implementation in ES6 Finally happy to see that now we can have iterators and generators. I also need to try to have private properties too so that we have well encapsulated data structures and I see that there are Proxies and Symbols which could help me do that.

Utils:

export const isDefAndNotNull = object =&gt;
  object !== undefined &amp;&amp; object !== null;

export const isIterable = object =&gt;
  isDefAndNotNull(object) &amp;&amp; typeof object[Symbol.iterator] === 'function';


Code:

import {isDefAndNotNull, isIterable} from "./Utils";

function *reverseArrayGenerator(arr) {
  let i = arr.length;
  while(--i &gt;= 0) {
    yield arr[i];
  }
}

const data = Symbol("data");

export default class {
  constructor(iterable) {
    this[data] = [];
    if (isIterable(iterable)) {
      for (let item of iterable) {
        this.push(item);
      }
    }
  }

  peek() {
    return this[data].slice(-1)[0];
  }

  push(item) {
    this[data].push(item);
  }

  pop() {
    return this[data].pop();
  }

  isEmpty() {
    return this[data].length === 0;
  }

  size() {
    return this[data].length;
  }

  toString() {
    let res = [];
    for (let item of this) {
      res.push(item);
    }
    return JSON.stringify(res.join(' '));
  }

  [Symbol.iterator]() {
    return reverseArrayGenerator(this[data]);
  }
}


Test:

import {strictEqual as equal} from "assert";
import Stack from "../src/Stack";

suite("Stack", () =&gt; {
  test("without iterator", () =&gt; {
    const s = new Stack();
    s.push(1);
    equal(s.size(), 1);
    equal(s.pop(), 1);
    equal(s.size(), 0);
  });

  test("with iterator", () =&gt; {
    let s = new Stack([1, 2, 3]);
    equal(s.size(), 3);
    s = new Stack('hello');
    equal(s.size(), 5);
    s = new Stack([{name: 'Foo'}, {name: 'Bar'}]);
    equal(s.size(), 2);
  });

  test("peek", () =&gt; {
    let s = new Stack([1, 2, 3]);
    equal(s.peek(), 3);
    s.pop();
    equal(s.peek(), 2);
  });

  test("iterator", () =&gt; {
    const s = new Stack([1, 2, 3]);
    let i = 3;
    for(let item of s) {
      equal(item, i);
      i--;
    }
  });
});


Reference: http://algs4.cs.princeton.edu/13stacks/Stack.java.html
Why are you using a symbol for the data? If you're hoping for private variables, you're out of luck.
return JSON.stringify(res.join(' ')); Why? Why not just return JSON.stringify([...this]) or something? Why both join into a string and JSON stringify?
return this[data].slice(-1)[0]; is inefficient as it needlessly copies the array for each call. return this[data][this.size()]; should be (if marginally) better.
Why is your reverseArrayGenerator generator function not in Utils?
isDefAndNotNull, while nice, can be shortened or completely dropped. Shortened to object != null which is exactly the same thing, or dropped altogether in favor of:&nbsp;&nbsp; object &amp;&amp; typeof object[Symbol.iterator] === 'function';


I won't repeat what the other answer says, but it's also correct.