Как преобразовать буквальный объект в пользовательский объект в JavaScript? - PullRequest
3 голосов
/ 25 ноября 2008

При написании тонны веб-приложений, использующих JSON / AJAX, я возвращаю тонны буквальных объектов JavaScript (JSON). Например, я могу запросить все кошки из GetCats.asp. Это вернуло бы:

[
  { 'id': 0, 'name': 'Persian' },
  { 'id': 1, 'name': 'Calico' },
  { 'id': 2, 'name': 'Tabby' }
]

Теперь это все объекты Cat с поведением. Однако, если я определяю объект Cat, функцию Cat () {}, я не знаю эффективного способа заставить эти буквальные объекты влиять на поведение определенного пользователем объекта.

Я могу сделать это, просто перебирая их и назначая функции, но это не будет красиво. Есть ли хороший, один или несколько строк способ как-то «навести» это поведение на эти литеральные объекты?

Ответы [ 5 ]

2 голосов
/ 25 ноября 2008

Нельзя обойти стороной тот факт, что вам придется перебирать все ваши простые объекты и изменять их на объекты другого типа. Вы не можете избежать петли. При этом вы можете создать конструктор, который принимает простой объект, подобный этому, и копирует эти значения в новый экземпляр.

Как это:

function Cat(c) {
  this.id = c.id;
  this.name = c.name;
}
Cat.prototype.meow = function() {alert('meow');}
Cat.prototype.displayName= function() {alert(this.name);}

var cats = [
  { 'id': 0, 'name': 'Persian' },
  { 'id': 1, 'name': 'Calico' },
  { 'id': 2, 'name': 'Tabby' }
];

for (i=0,len=cats.length; i<len; i++) {
  cats[i] = new Cat(cats[i]);
}

cats[0].meow();  // displays "meow"
cats[0].displayName();  // display "Persian"
0 голосов
/ 25 ноября 2008

Расширяя ответ @ Бенри.

Я считаю, что наличие функции расширения для копирования свойств одного объекта на другой является существенным. Есть полу-традиция помещать это в Объект; Object.extend() существует во многих небольших библиотеках (примечание: это не то же самое, что Object.prototype).

Object.extend = function ( take, give ) {
  for (var k in give) {
    if (give.hasOwnProperty(k)) {
      take[k] = give[k];
    }
  }
  return take;
}

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

function Cat (c) {
  Object.extend( this, ( c || this.defaults )  );
}

Object.extend(Cat.prototype, {

  meow : function() {
    alert( 'Meow, my name is ' + this.name );
  },

  defaults : {
    name : 'I have no name', 
    id   : null
  }

});

Вы можете создать свою армию кошек довольно просто:

var cats = [
  { 'id': 0, 'name': 'Persian' },
  { 'id': 1, 'name': 'Calico' },
  { 'id': 2, 'name': 'Tabby' }
];

for (i=0,len=cats.length; i<len; i++) {
  cats[i] = new Cat( cats[i] );
}

cats[0].meow();  // displays "meow, my name is Persian"
0 голосов
/ 25 ноября 2008

вы используете прототип фреймворка? если да - вот пример


var cats = [
    {id: 15, name: 'Tables', count:45 },
    {id: 23, name: 'Chairs', count:34 }
];
var catsObjects = [];
cats.each(function(item){
    var newObject = new Cat();
    Object.extend(newObject, item);
    catsObjects.push(newObject);
});

В основном функция Array.each такая же, как «for i и Object.extend - то же самое, что свойство за свойством, добавляя свойства в newObject

0 голосов
/ 25 ноября 2008

Если вы используете json2 парсер (или другой с совместимым интерфейсом), вы можете просто предоставить обратный вызов для замены необработанных объектов пользовательскими объектами:

var catSource = '[ { "id": 0, "name": "Persian" }, { "id": 1, "name": "Calico" }, { "id": 2, "name": "Tabby" } ]';

function Cat(id, name)
{
   this.id = id;
   this.name = name;
}
Cat.prototype = 
{
   toString: function()
   {
      return this.name;
   }
};

function doStuff()
{
   var cats = JSON.parse(catSource, function(key, val)
   {
      // some expression to detect the type of val 
      if ( val.id !== undefined && val.name !== undefined )
         return new Cat(val.id, val.name);
      return val;
   });
   alert(cats);
}
0 голосов
/ 25 ноября 2008

Назначьте каждому объекту соответствующий прототип:

var list = [
  { 'id': 0, 'name': 'Persian' },
  { 'id': 1, 'name': 'Calico' },
  { 'id': 2, 'name': 'Tabby' }
];


for (obj in list)
{
  obj.prototype = new Cat();
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...