0

Je crée une application basée sur le service GAS Spreadsheets qui lit/écrit & met à jour une ligne de données. J'ai un objet clé-valeur qui représente une ligne de données, comme les données d'exemple fournies dans l'extrait.Littéral d'objet avec fonction imbriquée en tant que prototype de données Objet

utilisation:

var exampleData = [{weekendVolume=5186270,midweekVolume=16405609}]; 
// tuple length 2 of two known values 

function _DataRecordObject(exampleData) { 
    this._endOfWeek = new Date().endOfWeek();// Date.prototype method 
} 

var _DataRecordMethods = { 

    weekEnding: function() { 
     return this._endOfWeek.formatDateString() 
    }, 
    weekMonth: function() { 
     return this._endOfWeek.getMonthLabelShort() 
    }, 
    /* Processed volume */ 
    weekendVolume: function() { 
     return 'weekendVolume' 
    }, 
    midweekVolume: function() { 
     return 'midweekVolume' 
    }, 
    totalVolumeProcessed: function() { 
     return _SumTotal( 
     this.weekendVolume(), 
     this.midweekVolume() 
     ) 
    } 
    } 

_DataRecordObject.prototype = _DataRecordMethods; 

Le new DataRecordObject est le prototype d'un objet de feuille qui fournit d'autres propriétés utiles. _SumTotal est une fonction d'assistance.

Ma question:

Quand j'appelle une nouvelle DataRecordObject avec la gamme de feuille comme argument, comment puis-je mettre à jour l'objet exampleData avec les nouvelles propriétés telles que totalVolumeProcessed?

Par exemple:

var foo = new _DataRecordObject(exampleData); 
Console.log(foo); 
//[{weekEnding='Aug-17',weekMonth=4,weekendVolume=5186270,midweekVolume=16405609,totalVolumeProcessed=21591879}] 

Je voudrais la flexibilité d'utiliser inheritence constructeur-prototype, mais en utilisant un modèle de style boilerplate comme objet littéraux. Mon intuition suggère que je dois passer les clés d'objet de données lors de la construction d'un nouvel objet dataRecordObject. Je suis un nouveau venu dans JavaScript et je n'ai pas encore compris ce que sont l'héritage, les prototypes et les modèles de design respectifs. Les usines et les modules, ou peut-être les observateurs semblent des modèles appropriés, mais mon expérience limitée avec JS est un facteur limitant pour résoudre mon problème.

+0

'totalVolumeProcessed' n'a pas besoin d'être mis à jour, c'est une méthode. – Bergi

+0

Oui, vous devriez probablement stocker la valeur du paramètre 'exampledata' dans une propriété de l'objet, tout comme vous l'avez fait avec' this._endOfWeek = ... '. – Bergi

+0

Hey @Bergi merci pour les commentaires.J'ai reformulé ma question car je pense que mon langage était trompeur. Fondamentalement, je veux mettre à jour l'objet 'exampleData' en utilisant les méthodes fournies par le prototype' _DataRecordMethods'. –

Répondre

0

Cela pourrait fonctionner pour vous.

1) Définir le prototype comme un objet littéral:

var methods = { 

    sayName: function() { 
    return "My name is " + this.name; 
    }, 

    sayAge: function() { 
    return "I am " + this.age + " years old"; 

    } 


}; 

2) Vous pouvez faire la variable « méthodes » globale ou définir dans la fonction suivante. La fonction crée un nouvel objet en utilisant la variable 'methods' comme prototype et la remplit avec les valeurs de l'argument 'data'.

function createNewObj (data) { 

    var data = data || null; 

    var result = Object.create(methods); 

    for (var key in data) { 

    if (data.hasOwnProperty(key)) { 

     result[key] = data[key]; 

    } 

    } 

    return result; 

} 

3) Apporter des choses ensemble

function test() { 

    var data = {name: "John", age: "32"}; 

    var row = createNewObj(data); 

    Logger.log(row.name); //logs 'John' 
    Logger.log(row.age); //logs '32' 
    Logger.log(row.sayName()); //logs 'My name is John' 
    Logger.log(row.sayAge()); //logs 'I am 32 years old' 
    Logger.log(Object.getPrototypeOf(row)); // returns contents of the 'methods' object literal 
    Logger.log(row.hasOwnProperty("sayName")); //logs 'false' because 'hasOwnProperty' doesn't go up the prototype chain 
    Logger.log("sayName" in row); //logs 'true' because 'in' goes up the chain 

} 

je vous suggère de jeter un oeil à ce billet de blog par Yehuda Katz qui plonge plus profondément dans des prototypes http://yehudakatz.com/2011/08/12/understanding-prototypes-in-javascript/ Il a des exemples de code beaucoup plus propre qui pourraient être utiles.

+0

Merci de répondre @ Anton-Dementiev, cela va un peu à la résolution du problème, mais la fonction est retournée à la place de la méthode, au lieu d'une valeur. Par exemple, en transmettant les données d'exemple, '[{{weekendVolume = 5186270, midweekVolume = 16405609}]', puis 'Logger.log (foo.totalVolumeProcessed()); // null' ou 'Logger.log (foo.totalVolumeProcessed); // function() { return _SumTotal (this.weekendVolume, this.midweekVolume) .sum; } ' –

+0

Et le lien vers Yehudi Katz est utile - Je pense qu'une solution peut être similaire aux sections _Native Object Orientation _... –

0

J'ai trouvé une solution qui étend la réponse de @ Anton-Dementiev. Sa suggestion de lire le Yehudi Katz était aussi très utile.

La création nouvelle fonction d'objet, _DataRecordObject est où la solution est ..

function _DataRecordObject(RowDataObject) { 
    this._endOfWeek = new Date().endOfWeek();// Date.prototype method 

    var data = RowDataObject || null; 
    var result = Object.create(_DataRecordMethods); 

    for (var key in data) { 
    if (data.hasOwnProperty(key)) { 
    // if value is present in the RowDataObject, 
    // then assign its value to the result 
     result[key] = data[key]; 
    } else { 
    // if not, the value is a method function, 
    // which should be evaluated in that context, 
    // and then return the method value as result 
     var foo = Object.getPrototypeOf(result)[ key ]; 
     result[key] = foo.call(data); 
    } 
    } 
    return result; 
} 
//simples 

Étant donné que les méthodes sont transmises en tant que fonctions de propriété, ils doivent être appelés comme des fonctions dans ce contexte.