代码之家  ›  专栏  ›  技术社区  ›  Skorejen

Node.js和ES6类错误

  •  2
  • Skorejen  · 技术社区  · 7 年前

    我有一个小错误在我的小编码操场,我只是找不到任何解决方案,我的错误,经过数小时的挣扎。

    我只想在 app.js 文件(从另一个 Post.js 文件)。(见第一段)

    这是代码和错误。

    ---下面的app.js文件

    'use strict';
    const bodyParser = require('body-parser'),
    mysql            = require('mysql'),
    express          = require('express'),
    app              = express(),
    Post             = require('./Post.js');
    
    app.get('/getposts', (req,res) => {
    let sql = 'select * from posts'
    let query = db.query(sql, (err,results) => {
        if(err) throw err;
    
        let id = results[0].id;
        let title = results[0].title;
        let body = results[0].body;
    
        var post = new Post(id,title,body);
    
    
        res.send('BLAH');
    });
    });
    

    --下面的Post.js文件

    'use strict';
    
    
    class Post {
    
    constructor(id,title,body) {
        this.id = 'id';
        this.title = 'title';
        this.body = 'body';
    }
    
    get id() {
        return this.id;
    }
    
    set id(id) {
        this.id = id;
    }
    
    get title() {
        return this.title;
    }
    
    set title(title) {
        this.title = title;
    }
    
    get body() {
        return this.body;
    }
    
    set body(body) {
        this.body = body;
    }
    
    write() {
        return `${this.id} that is the id, the title is ${this.title} and the body is : ${this.body}`
    }
    }
    
    module.exports = Post;
    

    --错误

    C:\Users\skor\Desktop\app\webbootcamp\Post.js:16
    set id(id) {
          ^
    at Post.set id [as id] (C:\Users\skor\Desktop\app\webbootcamp\Post.js:16:11)
    at Post.set id [as id] (C:\Users\skor\Desktop\app\webbootcamp\Post.js:17:17)
    at Post.set id [as id] (C:\Users\skor\Desktop\app\webbootcamp\Post.js:17:17)
    at Post.set id [as id] (C:\Users\skor\Desktop\app\webbootcamp\Post.js:17:17)
    at Post.set id [as id] (C:\Users\skor\Desktop\app\webbootcamp\Post.js:17:17)
    at Post.set id [as id] (C:\Users\skor\Desktop\app\webbootcamp\Post.js:17:17)
    at Post.set id [as id] (C:\Users\skor\Desktop\app\webbootcamp\Post.js:17:17)
    

    非常感谢你的帮助!

    3 回复  |  直到 7 年前
        1
  •  3
  •   Shl    7 年前

    您返回并设置实际的 getter setter 属于 id ,而不是更改 身份证件 财产 class ,所以:

    get id() {
        return this.id;
    }
    
    set id(id) {
        this.id = id;
    }
    

    将代码更改为:

    get id() {
        return this._id;
    }
    
    set id(id) {
        this._id = id;
    }
    

    同时也要在全班里改变你的getter和setter,就像这样:

    class Post {
      constructor(id, title, body) {
        this._id = id;
        this._title = title;
        this._body = body;
      }
    
      get id() {
        return this._id;
      }
    
      set id(id) {
        this._id = id;
      }
    
      get title() {
        return this._title;
      }
    
      set title(title) {
        this._title = title;
      }
    
      get body() {
        return this._body;
      }
    
      set body(body) {
        this._body = body;
      }
    
      write() {
        return `${this._id} that is the id, the title is ${this._title} and the body is : ${this._body}`
      }
    }
    

    同时确保 constructor ,当您将属性设置为使用值而不是字符串时,例如:而不是:

    this.id = 'id';
    

    像这样使用:

    this._id = id;
    

    使用前缀来区分 public private 属性,但由于JavaScript没有 (至今) 私有属性,此常用技术用于实现类似的结果,例如:和下划线 ( _ ) 之前 身份证件 ,因此: this._id ,即:

    class Point {
      constructor(x, y) {
        this._x = x;
        this._y = y;
      }  
    }
    

    有关此技术的有用资源:


    如中所述 this blog ,另外两种在JS中实现私有成员的技术是closer&WeakMap。这三种方法各有利弊。 近距离示例:

    class Person {
      constructor(name, age) {
        this.getAge = function () { return age; }
        this.setAge = function (newAge) { age = newAge; }
        this.getName = function () { return name; }
        this.setName = function (newName) { name = newName; }
      }
    }
    

    优势:

    • 私有成员的简单实现,不需要外部访问私有成员。

    缺点:

    • 这个类的每个对象都有自己的函数,它们不像前缀解决方案那样在原型上共享它们。

    • 成员太难访问-同一类的对象无法访问彼此的私有成员,这不是私有成员的标准实现。

    WeakMap的简短示例:

    /** @type {WeakMap<Person, {name: string, age: number}>} */
    const internal = new WeakMap();
    
    class Person {
      constructor(name, age) {
        internal.set(this, {name, age});
      }
    
      get age() {
        return internal.get(this).age;
      }
    
      set age(val) {
        internal.get(this).age = val;
      }
      // and the same for name
    }
    

    优势:

    • 原型上的共享函数。

    • 完全私有实现(同一类的对象可以访问彼此的私有成员

    缺点:

    • 不是一个简单的实现。

    一般来说,织布工是最好的方法,但并不总是这样。

        2
  •  2
  •   Willem van der Veen    7 年前

    每当设置对象的属性时,都会调用setter。构造函数调用setter。然后,因为setter执行以下操作:

    this.id = id;
    

    它将递归地调用自己,因此它会给出一个错误,因为堆栈将溢出。一种解决方案是删除setter和getter,只需按照以下方式获取和设置属性:

    class Post {
    
    constructor(id,title,body) {
        this.id = 'id';
        this.title = 'title';
        this.body = 'body';
    }
    
    
    write() {
        return `${this.id} that is the id, the title is ${this.title} and the body is : ${this.body}`
    }
    }
    
    let hey = new Post(1,'foo','bar');
    
    // set something like this:
    hey.id = 5;
    
    // get something like this:
    
    const id = hey.id;
        3
  •  1
  •   anjuc    7 年前

    我认为你的代码有问题。

    get id() {
        return this._id;
    }
    
    set id(id) {
        this._id = id;
    }
    

    我在你的代码中所做的更改 _ 在属性名称之前。