简体   繁体   English

Node.js和ES6类错误

[英]Node.js and ES6 class error

I have a small bug in my small coding playground and I just can't find any solution to my error after hours of struggling. 我在小型编码场所中遇到一个小错误,经过数小时的努力,我仍然找不到解决我错误的方法。

I simply want to create an object of a Post class in a app.js file (required from another Post.js file). 我只想在app.js文件中创建Post类的对象(需要另一个Post.js文件)。 (see first snippet) (请参见第一个代码段)

Here's the code and the error. 这是代码和错误。

--- app.js file below ---下面的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 file below -下面的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;

--Error - 错误

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)

Thanks so much for help! 非常感谢您的帮助!

You return and set the actual getter and setter of id , rather than changing the id property of the class , so: 您返回并设置id的实际gettersetter ,而不是更改classid属性,因此:

get id() {
    return this.id;
}

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

Change your code to this: 将代码更改为此:

get id() {
    return this._id;
}

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

And also change your getters and setters in your whole class like so: 并在整个班级中更改您的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}`
  }
}

Also make sure in the constructor , when you set the properties to use the values instead of strings, eg: instead of this: 还要确保在constructor ,当您将属性设置为使用值而不是字符串时,例如:

this.id = 'id';

use like this: 像这样使用:

this._id = id;

It's a common convention to use prefixes to distinguish public and private properties in languages, but since JavaScript doesn't have (yet) private properties, this common technique is used to achieve similar results, eg: and underscore ( _ ) before id , as so: this._id , ie: 它的使用前缀来区分共同约定publicprivate的语言特性,但由于JavaScript没有(还)私人性质,这种常见的技术用于实现类似的结果,如:和下划线_之前id ,如所以: this._id ,即:

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

Helpful resources regarding this technique: 关于此技术的有用资源:


As explained in this blog , another 2 techniques for implementing private members in JS you should be aware of are closer & WeakMap. 本博客所述 ,您还应该注意的另外两种在JS中实现私有成员的技术是close&WeakMap。 Each of the 3 different approaches has its own advantages and disadvantages. 三种不同方法中的每一种都有其自身的优点和缺点。 Short example for closer: 简短示例:

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; }
  }
}

Advantage: 优点:

  • Simple implementation of private members, without external access to the private members. 私有成员的简单实现,而无需外部访问私有成员。

Disadvantages: 缺点:

  • Every object of this class has its own functions and they don't share them on the prototype like in the prefix solution. 此类的每个对象都有其自己的功能,并且它们不像前缀解决方案那样在原型上共享它们。

  • The members are too much inaccessible - Objects of the same class can't access each other's private members, which is not the standard implementation of private members. 成员太多无法访问-相同类的对象无法访问彼此的私有成员,这不是私有成员的标准实现。

Short example of WeakMap: 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
}

Advantages: 好处:

  • Shared functions on prototype. 原型上的共享功能。

  • Fully private implementation (objects of the same class can access each other's private members 完全私有的实现(同一类的对象可以访问彼此的私有成员

Disadvantages: 缺点:

  • Not a simple implementation. 这不是一个简单的实现。

The WeakMap is the best approach in general, but not always. 通常,WeakMap是最好的方法,但并非总是如此。

Your setter is called whenever a property of the object is set. 只要设置了对象的属性,就会调用您的setter。 The constructor calls the setter. 构造函数调用设置器。 Then because the setter does the following: 然后,因为设置器将执行以下操作:

this.id = id;

It will call itself recursively and thus it gives an error because the stack will overflow. 它会递归调用自身,因此会产生错误,因为堆栈会溢出。 An solution is to remove your setters and getters and just get and set your properties in the following manner: 一个解决方案是删除您的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; 

I think the problem with your code is this. 我认为您的代码的问题是这样的。

get id() {
    return this._id;
}

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

The change that I have made in your code is putting _ before attribute names. 我在您的代码中所做的更改是将_放在属性名称之前。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM