Ошибка при использовании функции генератора в качестве значения 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());