Javascript 将生成器函数用作WeakMap的值时出错

Javascript 将生成器函数用作WeakMap的值时出错,javascript,ecmascript-6,es6-generator,Javascript,Ecmascript 6,Es6 Generator,我正在自己建立一个链表。我尝试将生成器指定为构造函数中键/值WeakMap的值。\u迭代器是一个弱映射,因为它是一个私有成员,我想用它对我的数据结构进行简单的迭代,但我不想让生成器在外部可见,否则我会破坏抽象。但是我有一个错误SyntaxError:missing(在正式参数之前)。问题是什么 class Node{ constructor(value){ this.value = value; this.next = null; }

我正在自己建立一个链表。我尝试将生成器指定为构造函数中键/值WeakMap的值。
\u迭代器是一个弱映射,因为它是一个私有成员,我想用它对我的数据结构进行简单的迭代,但我不想让生成器在外部可见,否则我会破坏抽象。但是我有一个错误
SyntaxError:missing(在正式参数之前)。问题是什么

  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);*/

函数表达式不能有计算名称,该语法只允许在对象文本成员或类成员上使用,因此请定义
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的一些更现代的功能进行重写,如:

类节点{
next=null;
构造函数(值){
这个值=值;
}
}
类SingleLinkedList{
#尺寸=0;
#head=null;
#tail=null;
//只读获取访问器属性
获取大小(){
将此返回。#大小;
}
我是空的(){
返回此值。#size==0;
}
//插入具有所需值的新节点(在尾部)
推送(值){
const node=新节点(值);
if(this.isEmpty()){
这个。#头=节点;
}否则{
this.#tail.next=节点;
}
//以下说明对这两种情况都是通用的。
这个。#tail=node;
这个#size++;
//允许多个推送呼叫
归还这个;
}
//生成器返回值
*[符号.迭代器](){
for(让current=this.#head;current;current=current.next){
收益现值;
}
}
//每个节点的值
toString(){
return[…this].join(“”);
}
}
const myLinkedList=new SingleLinkedList();
myLinkedList.push(3)和push(5);

console.log(myLinkedList.toString());
函数表达式不能有计算名称,该语法只允许在对象文本成员或类成员上使用,因此请像下面这样定义
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的一些更现代的功能进行重写,如:

类节点{
next=null;
构造函数(值){
这个值=值;
}
}
类SingleLinkedList{
#尺寸=0;
#head=null;
#tail=null;
//只读获取访问器属性
获取大小(){
将此返回。#大小;
}
我是空的(){
返回此值。#size==0;
}
//插入具有所需值的新节点(在尾部)
推送(值){
const node=新节点(值);
if(this.isEmpty()){
这个。#头=节点;
}否则{
this.#tail.next=节点;
}
//以下说明对这两种情况都是通用的。
这个。#tail=node;
这个#size++;
//允许多个推送呼叫
归还这个;
}
//生成器返回值
*[符号.迭代器](){
for(让current=this.#head;current;current=current.next){
收益现值;
}
}
//每个节点的值
toString(){
return[…this].join(“”);
}
}
const myLinkedList=new SingleLinkedList();
myLinkedList.push(3)和push(5);

console.log(myLinkedList.toString());
我在这里看到一个问题
函数*[Symbol.iterator]()
我在这里看到一个问题
函数*[Symbol.iterator]()
谢谢!我不记得这个限制。生成器已经是一个可移植的工具了。现在,它可以工作了。我很欣赏你的代码。我知道一些关于类和私人成员的消息,但他们正在提案、起草阶段。此外,我知道有巴贝尔,但目前我还没有进入生产阶段(我已经学习Javascript两三个月了,我来自纯OOP世界)我也不想被网页包之类的东西卡住。但是现在我读到Google now配备了私有类字段,我将使用它们,代码变得可读性和直观性都很好。再次感谢。@Umbert够公平的了。如果你不进行传输,我个人会避免使用私有类字段,因为我不知道旁边有任何浏览器s Chrome目前支持它们,即使它们是标准化的。你在闭包中使用了
WeakMap
,事实上就是这样。谢谢!我不记得这个限制。生成器已经是一个可移植的。现在,它可以工作了。我很欣赏你的代码。我知道一些关于类和私有成员的新闻,但是他们处于提案、起草阶段。此外,我知道有巴贝尔,但目前我还没有进入生产阶段(我已经学习Javascript两三个月了,我来自纯OOP世界)我也不想被网页包之类的东西卡住。但是现在我读到Google now配备了私有类字段,我将使用它们,代码变得可读性和直观性都很好。再次感谢。@Umbert够公平的了。如果你不进行传输,我个人会避免使用私有类字段,因为我不知道旁边有任何浏览器尽管它们是标准化的,但目前支持它们的Chrome。您在结束时使用了
WeakMap
,事实上就是这样。