我正在学习构造函数模式。
为了锻炼我正在学习的东西,我正在构建一个名为Book
的内存模型,其灵感来自Mongoose API:
var assert = require("assert");
var Book = (function() {
var books = [];
var constructor = function(title, author, genre) {
assert.ok(title, "title cannot be undefined");
assert.ok(author, "author cannot be undefined");
assert.ok(genre, "genre cannot be undefined");
this.title = title;
this.author = author;
this.genre = genre;
this.save = function() {
books.push(this);
};
this.description = this.title + "is a " + this.genre + " by " + this.author;
};
constructor.find = function() {
return books;
};
return constructor;
}());
使用此模型,我可以创建Book
个实例,并将save
个实例创建到内存存储中:
var book = new Book("The Great Gatsby", "F. Scott Fitzgerald", "Novel");
book.save();
var books = Book.find();
console.log(books);
// [ { title: 'The Great Gatsby',
// author: 'F. Scott Fitzgerald',
// genre: 'Novel',
// save: [Function],
// description: 'The Great Gatsbyis a Novel by F. Scott Fitzgerald' } ]
如何从输出中删除功能属性“save”?我只想显示属性。
我需要知道因为,我想使用Express将book
发送给客户端,我不想用函数回复响应。
(我来自C#背景,在C#中,我会覆盖名为System.Object
的{{1}}基类中的函数,该函数 ToString
使用在内部。我不知道JavaScript中的任何等效内容。)
答案 0 :(得分:1)
是的,可以覆盖默认的toString输出:
var Book = (function() {
var books = [];
var constructor = function(title, author, genre) {
assert.ok(title, "title cannot be undefined");
assert.ok(author, "author cannot be undefined");
assert.ok(genre, "genre cannot be undefined");
this.title = title;
this.author = author;
this.genre = genre;
this.save = function() {
books.push(this);
};
this.description = this.title + "is a " + this.genre + " by " + this.author;
};
constructor.find = function() {
return books;
};
constructor.prototype.toString = function() {
return JSON.stringify(this);
};
return constructor;
}());
答案 1 :(得分:0)
简短而又狡猾的方式:
books = JSON.parse(JSON.stringify(books));
console.log(books);
注意:当您使用
JSON.stringify
快递将对象传递到客户端时,会发生res.json(book)
。如果你想要的只是将对象发送给客户端,那么除了将对象传递给res.json([obj|array])
之外,你不需要做任何事情。
将行为封装在对象本身上。
var Book = (function() {
var books = [];
var constructor = function(title, author, genre) {
assert.ok(title, "title cannot be undefined");
assert.ok(author, "author cannot be undefined");
assert.ok(genre, "genre cannot be undefined");
this.title = title;
this.author = author;
this.genre = genre;
this.save = function() {
books.push(this);
};
this.description = this.title + "is a " + this.genre + " by " + this.author;
this.stripFunctions = function () {
var item = this;
Object.keys(item).forEach(function (key) {
if (item.hasOwnProperty(key) && typeof item[key] === 'function') {
delete item[key];
}
});
return item;
};
};
constructor.find = function() {
return books;
};
return constructor;
}());
books = books.map(function (book) { return book.stripFunctions(); });
console.log(books);
请注意,上述方法会删除对象实例中的所有函数,这意味着您在此之后将无法再调用它们。
PS - 它不是你问题的一部分,但你应该考虑为你的构造函数添加原型方法,这样你就不会在每次创建{{1}的实例时创建新函数}。
另外,如果你使用Book
从快递发送对象,那么我会重新进行迭代,然后它会为你调用res.json
,当你对一个对象进行字符串化时,无论如何都会剥离函数
答案 2 :(得分:0)
在原型上定义函数:
var Book = (function() {
var books = [];
function Book (title, author, genre) {
assert.ok(title, "title cannot be undefined");
assert.ok(author, "author cannot be undefined");
assert.ok(genre, "genre cannot be undefined");
this.title = title;
this.author = author;
this.genre = genre;
this.description = this.title + "is a " + this.genre + " by " + this.author;
}
Book.prototype.save = function () {
books.push(this);
};
Book.find = function () {
return books;
};
return Book;
}());
如果我可以提供帮助,我想在Book构造函数中封装该行为。
这听起来像是一个奇怪的要求,但如果你确实需要(无论出于何种原因),你可以使用Object.defineProperty
来定义函数而不使其可枚举:
var Book = (function() {
var books = [];
function Book (title, author, genre) {
assert.ok(title, "title cannot be undefined");
assert.ok(author, "author cannot be undefined");
assert.ok(genre, "genre cannot be undefined");
this.title = title;
this.author = author;
this.genre = genre;
this.description = this.title + "is a " + this.genre + " by " + this.author;
Object.defineProperty(this, 'save', {
value: function () {
books.push(this);
}
});
}
Book.find = function () {
return books;
};
return Book;
}());