Javascript: Как превратить массив объектов JSON обратно в прототипы совместного использования типов объектов? - PullRequest
6 голосов
/ 08 июня 2011

Если у вас есть массив объектов продукта, созданный из JSON, как бы вы добавили метод-прототип к объектам продукта, чтобы они все указывали на один и тот же метод? Как бы вы научили JavaScript распознавать все объекты продукта в массиве как экземпляры одного класса, не воссоздавая их?

Если я, например, раскрываю массив Продуктов JSON и хочу, чтобы у каждого продукта в массиве был метод-прототип, как мне добавить один метод-прототип для каждой копии Продукта?

Сначала я подумал, что у меня есть конструктор Product, который принимает данные JSON продукта в качестве параметра и возвращает новый продукт с прототипами и т. Д., Который заменит данные, отправленные с сервера. Я думаю, что это будет нецелесообразно, потому что вы воссоздаете объекты. Мы просто хотим добавить функции, общие для всех объектов.

Возможно ли $.extend свойства прототипа объекта для объекта JSON, чтобы каждый объект JSON ссылался на одни и те же функции (а не на их копию)?

Например:

var Products = [];
Products[0] = {};
Products[0].ID = 7;
Products[0].prototype.GetID = function() { return this.ID; };
Products[1].ID = 8;
Products[1].prototype = Products[0].prototype;  // ??

Я знаю, что это выглядит плохо, но что, если вы JQuery $.extend методы для каждого прототипа объекта Product: создать объект, загруженный прототипами, а затем $.extend этот объект поверх существующих объектов Product? Как бы вы это закодировали? Каковы лучшие возможности?

Ответы [ 6 ]

2 голосов
/ 09 июня 2011

Во-первых, одна проблема заключается в том, что prototype методы связаны, когда объект создан , поэтому присвоение объекту prototype не будет работать:

var Products = [];
Products[0] = {};
Products[0].prototype.foo = function () { return 'hello' } // ***

Products[0].foo(); // call to undefined function

(*** На самом деле код здесь не выполняется, поскольку prototype не определено.)

Таким образом, чтобы прикрепить объекты, вам необходимо присвоить объекту реальные функции:

Products[0].foo = function () { return 'hello'; };

Вы можете создать вспомогательную функцию для этого:

var attachFoo = (function () { // Create a new variable scope, so foo and
                               // bar is not part of the global namespace

    function foo() { return this.name; }
    function bar() { return 'hello'; }

    return function (obj) {
        obj.foo = foo;
        obj.bar = bar;
        return obj; // This line is actually optional,
                    // as the function /modifies/ the current
                    // object rather than creating a new one
    };

}());

attachFoo(Products[0]);
attachFoo(Products[1]);

// - OR -
Products.forEach(attachFoo);

Делая это таким образом, все ваши obj.foo и obj.bar будут ссылаться на одни и те же foo() и bar().

2 голосов
/ 08 июня 2011

Во-первых, вы не изменяете Products[0].prototype, вы модифицируете Object.prototype, который поместит эту функцию в прототип всех объектов, а также сделает ее перечисляемой в каждом цикле for, который касается объекта..

Кроме того, это неправильный способ изменения прототипа, и ({}).prototype.something сгенерирует ошибку TypeError, поскольку .prototype не определено.Вы хотите установить его с помощью ({}).__proto__.something.

. Если вы хотите, чтобы это был определенный экземпляр, вам нужно создать этот экземпляр, в противном случае это будет экземпляр Object.

Возможно, вы захотитечто-то вроде:

var Product = function(ID) {
    if (!this instanceof Product)
        return new Product(ID);

    this.ID = ID;

    return this;
};

Product.prototype.GetID = function() { 
    return this.ID;
};

Затем заполните массив, вызвав new Product(7) или любой другой идентификатор.

1 голос
/ 17 июня 2011

IMO Я нашел довольно хороший ответ прямо здесь:

Строка возврата из междоменного запроса AJAX

... Я мог бы сериализовать свои данныев сервисе в виде строки JSON, а затем обернуть это в формате JSONP?Я полагаю, что когда он приходит к клиенту, он передает строку JSON в функцию обратного вызова.Это неплохая идея.Думаю, у меня также была бы возможность отправить не-JSON-строку, что позволило бы мне просто использовать eval в функции обратного вызова для создания новых объектов Person.Я думаю, что это было бы более эффективным решением как по скорости, так и по использованию памяти на стороне клиента.

1 голос
/ 10 июня 2011

Итак, если я все правильно понимаю, это более полный пример идеи KOGI:

// Create a person class
function Person( firstName, lastName ) {
    var aPerson = {
        firstName:  firstName,
        lastName:   lastName
    }

    // Adds methods to an object to make it of type "person"
    aPerson = addPersonMethods( aPerson );
    return aPerson;
}
function addPersonMethods( obj ) {
    obj.nameFirstLast = personNameFirstLast;
    obj.nameLastFirst = personNameLastFirst;
    return obj;
}
function personNameFirstLast() {
    return this.firstName + ' ' + this.lastName;
}
function personNameLastFirst() {
    return this.lastName + ', ' + this.firstName;
}

Итак, с помощью этой структуры вы определяете методы, которые будут добавлены в функцию addPersonMethods. Таким образом, методы объекта определяются в одном месте, и затем вы можете сделать что-то вроде этого:

// Given a variable "json" with the person json data
var personWithNoMethods = JSON.parse( json );    // Use whatever parser you want
var person = addPersonMethods( personWithNoMethods );
1 голос
/ 08 июня 2011

Можно попробовать сделать что-то вроде этого (без jquery) Базовый объект-прототип:

function Product(id){
    this.id = id;
}
Product.prototype.getId() = function(){return this.id;};

var Products = [];
Products[0] = new Product(7);
Products[1] = new Product(8);
Products[2] = new Product(9);

alert(Products[2].getId());
1 голос
/ 08 июня 2011

Вы можете сделать это ...

function product( )
{
   this.getId = product_getId;

    // -- create a new product object
}

function product_getId( )
{
   return this.id;
}

Таким образом, хотя у вас будет несколько экземпляров класса продукта, все они указывают на экземпляр функции.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...