Ошибка при использовании функции генератора в качестве значения WeakMap

Я сам создаю связанный список. Я попытался назначить генератор как значение ключа / значения WeakMap в конструкторе. В_iteratorявляется WeakMap, потому что это частный член, который я хочу использовать для простого перебора структуры данных, но я не хочу, чтобы генератор был видимым снаружи, потому что в противном случае я нарушу абстракцию. Но у меня ошибкаSyntaxError: missing ( before formal parameters. В чем проблема?

  class Node{
     constructor(value){
        this.value = value;
        this.next = null;
     }
  }

  //IIFE function that return the class. 
  const SingleLinkedList = (() => { //Here use IIFE to create a new block scope for private variables
     let _counts = new WeakMap();
     let _head = new WeakMap();
     let _tail = new WeakMap();
     let _iterator = new WeakMap();

     class SingleLinkedList {
        constructor() {
           _counts.set(this, 0);
           _head.set(this, null);
           _tail.set(this, null);
           let instance = this;//closure
           _iterator.set(this,(function* [Symbol.iterator](){
              let n=_head.get(instance);
              while(n){
                 yield n;
                 n = n.next;
              }
           }));
        }


        get counts() { //read only get accessor property
           return _counts.get(this);
        }

        isEmpty() {
           return !this.counts;  //or return !_head.get(this)
        }

        //insert a new Node (in tail) with the desired value
        push(value) {
           let n = new Node(value);
           if (this.isEmpty()) 
              _head.set(this, n);
           else {
              let tail = _tail.get(this); //tail is a pointer to the node-tail
              tail.next = n; //old tail-node will point to new node
           }

           //the following instructions are common to both the cases.
           _tail.set(this, n); //set new tail
           _counts.set(this, this.counts+1); //increment item counter

           return this; //to allow multiple push call
        }

        //Generator to return the values
        *[Symbol.iterator](){

           let n = _head.get(this); 
           while(n){
              yield n.value;
              n=n.next;
           }
        }
        //the the values of each node
        print() {
           let output = "";
           for(let el of this)
              output += `${el} `;
           console.log(output);
        }
     }
     return SingleLinkedList;
  })();

  let myLinkedList = new SingleLinkedList();
  myLinkedList.push(3);
  myLinkedList.push(5);
  myLinkedList.print();

  /*for(let x of myLinkedList)
     console.log(x);*/

1 ответ

Решение

Выражения функций не могут иметь вычисляемых имен, этот синтаксис разрешен только для членов литералов объекта или членов класса, поэтому определите конструктор вашего SingleLinkedList как это вместо этого:

constructor() {
  _counts.set(this, 0);
  _head.set(this, null);
  _tail.set(this, null);
  let instance = this;//closure
  _iterator.set(this, function* (){
// remove the computed name ---^
    let n=_head.get(instance);
    while(n){
      yield n;
      n = n.next;
    }
  });
}

Возможно, еще более полезно знать, как в будущем отлаживать синтаксические ошибки, чтобы вам больше не приходилось задавать подобные вопросы. Если вы откроете консоль разработчика, нажав F12, вы увидите журнал, который выглядит примерно так:

Щелкните эту ссылку, и вы сразу перейдете к месту ошибки:


Просто для удовольствия, вот мой предложенный вариант перезаписи с использованием некоторых более современных функций ECMAScript, таких как частные поля:

class Node {
  next = null;

  constructor (value) {
    this.value = value;
  }
}

class SingleLinkedList {
  #size = 0;
  #head = null;
  #tail = null;

  // read only get accessor property
  get size () {
    return this.#size;
  }

  isEmpty () {
    return this.#size === 0;
  }

  // insert a new Node (in tail) with the desired value
  push (value) {
    const node = new Node(value);

    if (this.isEmpty()) {
      this.#head = node;
    } else {
      this.#tail.next = node;
    }

    // the following instructions are common to both the cases.
    this.#tail = node;
    this.#size++;

    // to allow multiple push call
    return this;
  }

  // generator to return the values
  *[Symbol.iterator] () {
    for (let current = this.#head; current; current = current.next) {
      yield current.value;
    }
  }

  // the the values of each node
  toString () {
    return [...this].join(' ');
  }
}

const myLinkedList = new SingleLinkedList();
myLinkedList.push(3).push(5);
console.log(myLinkedList.toString());

Другие вопросы по тегам