These articles are abridged from my book on Learning Apps Script and Office to Apps migration.
Going GAS, from VBA to Google Apps Script.
Available in ebook or print from O’Reilly or Amazon or any other good bookshop.
ECMAScript 5 introduced a new way of creating objects, giving better control over properties and bringing some standardization. Apps Script is based on ECMAScript 3, but it also has some things from ES5, including Object.create.
Here’s how to use it.
Usual way to create objects.
We are all used to creating objects like this,
1 2 3 4 5 6 7 8 9 10 |
var mammal = { livesOnLand:true, legs:4, warmBlooded:true, vertebrate:true, hair:true, layEggs:false, milk:true, kind:'mammal' }; |
1 2 3 4 5 6 7 8 9 10 11 12 13 |
function Mammal () { this.livesOnLand = true; this.legs = 4; this.warmBlooded = true; this.vertebrate = true; this.hair = true; this.layEggs = false; this.milk = true; this.kind = 'mammal'; }; var mammal = new Mammal(); |
or modifying the function prototype of the constructor
1 2 3 4 5 6 7 |
function Mammal () { } Mammal.prototype.legs = 4; // etc... var mammal = new Mammal(); |
1 2 3 4 5 6 |
function SeaMammal () { Mammal.call (this); this.legs =0; this.livesOnLand = false; } var seaMammal = new SeaMammal(); |
Using Object.create
1 |
var ob = Object.create (thePrototype , { specific properties }); |
Creating a prototype.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 |
var Mammal = Object.create (null, { warmBlooded:{ value:true, enumerable:true }, vertebrate:{ value:true, enumerable:true }, introduction:{ get:function () { return 'Im a kind of ' + this.kind + ' called a ' + this.name + ' and I eat ' + this.eats + '. I' + (this.livesOnLand ? '' : " don't" ) + ' live on land and I have ' + this.legs + ' limbs.'; } }, build: { value: function (name, eats) { this.name = name; this.eats = eats; return this; } } }); |
1 2 |
Logger.log (JSON.stringify(Mammal)); {"warmBlooded":true,"vertebrate":true} |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
var LandMammal = Object.create (Mammal, { livesOnLand:{ value: true, enumerable:true }, legs:{ value:4, enumerable:true }, kind:{ value:'land mammal', enumerable:true } }); |
1 2 |
Logger.log (JSON.stringify(LandMammal)); {"livesOnLand":true,"legs":4,"kind":"land mammal"} |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
var SeaMammal = Object.create (Mammal, { livesOnLand:{ value: false, enumerable:true }, legs:{ value:0, enumerable:true }, kind:{ value:'sea mammal', enumerable:true } }); |
1 2 |
Logger.log (JSON.stringify(SeaMammal)); {"livesOnLand":false,"legs":0,"kind":"sea mammal"} |
Creating object instances
1 2 |
var dog = Object.create(LandMammal).build ('dog','meat'); var rat = Object.create(LandMammal).build ('rat','anything'); |
1 2 |
Logger.log (JSON.stringify(rat)); {"name":"rat","eats":"anything"} |
1 2 |
var whale = Object.create(SeaMammal).build ('whale', 'krill'); var dolphin = Object.create(SeaMammal).build('dolphin','fish'); |
1 2 |
Logger.log (JSON.stringify(whale)); {"name":"whale","eats":"krill"} |
Using getters
1 2 |
Logger.log(dolphin.introduction); Im a kind of sea mammal called a dolphin and I eat fish. I don't live on land and I have 0 limbs. |
1 2 |
Logger.log(dog.introduction); Im a kind of land mammal called a dog and I eat meat. I live on land and I have 4 limbs. |
Stringifying the prototype chain.
1 2 3 4 5 6 7 8 |
Logger.log (JSON.stringify(whale)); {"name":"whale","eats":"krill"} Logger.log (JSON.stringify(Object.getPrototypeOf(whale))); {"livesOnLand":false,"legs":0,"kind":"sea mammal"} Logger.log (JSON.stringify(Object.getPrototypeOf(Object.getPrototypeOf(whale)))); {"warmBlooded":true,"vertebrate":true} |
Generalizing prototype chain stringification
1 2 3 4 5 6 7 8 9 |
function combineChain (ob,obCombined) { return ob ? combineChain( Object.getPrototypeOf(ob), Object.keys(ob).reduce(function(p,c) { if (!p.hasOwnProperty(c)) p[c] = ob[c]; return p; }, obCombined || {})) : obCombined; } |
1 2 |
Logger.log (JSON.stringify(combineChain(whale))); {"name":"whale","eats":"krill","livesOnLand":false,"legs":0,"kind":"sea mammal","warmBlooded":true,"vertebrate":true} |