Skip to content

11. Object to String (pOTS.js)

Pimp Trizkit edited this page Mar 10, 2018 · 2 revisions
<< Previous        Back to Table of Contents        Next >>

    "No, no, no. That's not where I'm going with this. I'm not stringing you along, quit objectifying me." - PT

This will create a string whose contents are a valid Javascript object declaration, in string form. Like Stringify. This can be used for data transport and with eval(), which can be used for object cloning, god help you.

  • The result from this function will be a string representation of your object, even if your object has embedded objects and arrays, and even if those objects or arrays have even further embedded objects and arrays
  • Arrays are stored with [] instead of {} and thus dont have key/value pairs, just values. Like regular arrays. Therefore, they get created like arrays do.
  • All string (including key names) are quoted, this is not necessary unless those strings have special characters (like a space or a slash). But, I didn't feel like detecting this just to remove some quotes that would otherwise still work fine, god help me.
  • The returned string can then be used with eval() (with added "()" to the string) or just dumping it into a var thru string manipulation. Thus, re-creating your object again, from text.
  • The only way I could think of to detect type array was to check for the presence of length. Because JavaScript really stores arrays as objects, I cant actually check for type array (there is no such type!). If anyone else knows a better way, I would love to hear it. Because, if your object also has a property named length then this function will mistakenly treat it as an array.
  • This does print very similar to FireFox's toSource(). However, FireFox's toSource() will print the infinite recursion one time, where as pOTS() will kill it immediately.

(I originally posted this as an answer to a question on StackOverflow)

Code:

const pOTS=(o)=> {
    if (!o) return null;
    let str="",na=0,k,p;
    if (typeof(o) == "object") {
        if (!pOTS.check) pOTS.check = new Array();
        for (k=pOTS.check.length;na<k;na++) if (pOTS.check[na]==o) return '{}';
        pOTS.check.push(o);
    }
    k="",na=typeof(o.length)=="undefined"?1:0;
    for(p in o){
        if (na) k = "'"+p+"':";
        if (typeof o[p] == "string") str += k+"'"+o[p]+"',";
        else if (typeof o[p] == "object") str += k+pOTS(o[p])+",";
        else str += k+o[p]+",";
    }
    if (typeof(o) == "object") pOTS.check.pop();
    if (na) return "{"+str.slice(0,-1)+"}";
    else return "["+str.slice(0,-1)+"]";
}

Usage:

let o = {description:"mostly harmless", fashionable:false, backwaters:true, answer:42, sector:["ZZ9","Plural","Z","Alpha"], func:()=>"myFunc"};
let b = {name:"earth", stats:o, creator:null, dont:undefined, panic:null};
let j = {planet:b, creator:"Douglas Adams", 42:"answer"};
b.creator = j;

pOTS ( o ); // {'description':'mostly harmless','fashionable':false,'backwaters':true,'answer':42,'sector':['ZZ9','Plural','Z','Alpha'],'func':()=>"myFunc"}

pOTS ( b ); // {'name':'earth','stats':{'description':'mostly harmless','fashionable':false,'backwaters':true,'answer':42,'sector':['ZZ9','Plural','Z','Alpha'],'func':()=>"myFunc"},'creator':{'42':'answer','planet':{},'creator':'Douglas Adams'},'dont':undefined,'panic':null}

pOTS ( j ); // {'42':'answer','planet':{'name':'earth','stats':{'description':'mostly harmless','fashionable':false,'backwaters':true,'answer':42,'sector':['ZZ9','Plural','Z','Alpha'],'func':()=>"myFunc"},'creator':{},'dont':undefined,'panic':null},'creator':'Douglas Adams'}

eval( "("+pOTS(j)+")" ).planet.stats.func(); // Running a function from a clone. Returns "myFunc" string.

Return:

A String representation of the Object. This is a valid Javascript object string declaration. Or null if a non-string was passed in.

Params:

pOTS(o)

o = < Object > * REQUIRED

  • The Object to stringify, or convert to a valid Javascript object string.
  • null will be return if o is omitted or a falsy is passed in.
  • The returned string can be passed into eval(). But first, you will need to wrap the string in ().
  • If there are links to objects that link back to itself (infinite recursion), then pOTS will kill the recursion the first time it sees a repeated object. Unlike FireFox which will print that already printed object a second time. pOTS helps to prevent duplicates in data transport.
  • Objects that have already been printed thru pOTS's recursion will print as {} the second time.
  • When cloning, keep in mind, any infinite recursion will be stripped out and replaced with {} and references will be resolved.

Clone this wiki locally