Javascript:如何将对象的JSON数组返回到对象类型共享原型中

Javascript: How to turn a JSON array of object back in to the Object type sharing prototypes?

本文关键字:对象 返回 类型 共享 原型 数组 JSON Javascript      更新时间:2023-09-26

如果您有一个从JSON创建的产品对象数组,您将如何向产品对象添加原型方法,使它们都指向同一个方法?如何训练JavaScript识别数组中的所有产品对象都是同一类的实例,而不重新创建它们?

例如,如果我取下一个Products的JSON数组,并希望数组中的每个产品都有一个原型方法,我将如何将单个原型方法添加到每个product副本中?

我首先想到了一个Product构造函数,它将产品JSON数据作为参数,并返回一个带有原型等的新Product,它将取代从服务器发送的数据。我认为这是不切实际的,因为你正在重新创建对象。我们只想添加所有对象通用的函数。

是否可以将对象的原型属性$.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对象原型的方法:创建一个加载了原型的对象,然后在现有的Product对象上$.extend那个对象呢?你会怎么编码?更好的可能性是什么?

首先,您不是在修改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)或任何ID来填充数组。

首先,一个问题是,当对象被创建时,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.fooobj.bar都将引用相同的foo()bar()

因此,如果我正确地理解了这一切,这是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 );

你可以这样做。。。

function product( )
{
   this.getId = product_getId;
    // -- create a new product object
}
function product_getId( )
{
   return this.id;
}

这样,尽管您将拥有产品类的几个实例,但它们都指向函数的实例。

可以尝试这样做(没有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());

IMO我在这里找到了一个很好的答案:

跨域AJAX请求返回字符串

我可以把我的服务中的数据作为JSON字符串然后进一步将其封装在JSONP中总体安排我想当它来到它将向客户端提供JSON回调函数的字符串。这不是个坏主意。我想我会的还可以选择发送非JSON字符串,这可能允许我只在回调中使用eval函数来创建新的Person对象。我想这会更在速度和客户端内存使用情况。