如何从对象输出中删除函数?

时间:2015-06-09 18:20:45

标签: javascript c# node.js ecmascript-5

我正在学习构造函数模式

为了锻炼我正在学习的东西,我正在构建一个名为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中的任何等效内容。)

3 个答案:

答案 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;
}());