2015-06-09 2 views
1

Я узнаю о шаблоне конструктора .Как удалить функции из вывода объекта?

Чтобы осуществить то, что я учусь, я строй модели в памяти под названием 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' } ] 

Как удалить свойство функции «сохранить» от выхода? Я только хочу показать свойства.

Мне нужно знать, потому что я хочу отправить book клиенту с помощью Express, и я не хочу свертывать ответ с функциями.

(я родом из C# фоне и в C#, я бы переопределить функцию в System.Object базового класса ToString, что функции какconsole.log использование внутри. Я не знаю ни одного эквивалента в JavaScript.)

+1

как вы отправляете его от экспресс-клиента? JSON? если это так, JSON удаляет функции для вас ... – dandavis

ответ

0

Короткий, но Hacky способ:

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 - Это не часть вашего вопроса, но вы должны рассмотреть возможность добавления методов к прототипу вашего конструктора, чтобы вы не создавали новые функции при создании экземпляра Book.

Кроме того, я буду повторять, что если вы отправляете объекты с экспресса с помощью res.json, тогда он вызывает для вас JSON.stringify, а когда вы создаете объект, функции все равно удаляются.

+0

Если я могу помочь, я хочу инкапсулировать это поведение в конструкторе 'Book'. –

+0

Я включил более общее решение для вас, которое будет перебирать все свойства объектов в коллекции, проверить, является ли это значение функцией, и удаляет свойство, если оно есть. Я добавлю версию конструктора. Одну секунду. – Chev

+0

@Angularnoob сделано. – Chev

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

Да, это возможно переопределить значение по умолчанию для вывода строки:

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; 
}()); 
+0

Это отличный ответ, потому что он параллелен тому, что OP говорит, что он знаком с C#. Переопределяет 'toString' с вызовом' JSON.stringify' :) – Chev

Смежные вопросы