JSON
JavaScript
Børre Stenseth

JSON

Hva

JSON (JavaScript Object Notation) er, slik vi skal betrakte det, en måte å pakke data på slik at de blir enkle å bearbeide på klientsiden. Hvis vi har AJAX som referanseramme betyr det at vi skal bruke JSON som format når vi returnerer svar på en forespørsel, en XMLHttpRequest.

Nettleseren skal eksponere et objekt JSON, med to metoder: parse() og stringify(). parse skal ta en string som input og returnere et javaskript-objekt. stringify skal gjøre det motsatte.

En beskrivelse av hvordan tekst skal formateres for å kunne tolkes som JSON finner du på json.org [1] .

parse

Grunnlaget for JSON er at vi kan tolke tekstformat som objekter i et javaskript. Vi kan f.eks. gjøre slik:

var T='{"navn":"Ole","adresse":"Halden"}';
var person=JSON.parse(T);
alert(person.navn);	

Nøkkelen er parse-funksjonen som tolker teksten som javascriptkode. Siden JavaScript er et interpretert språk er dette egntlig den mekansimen som brukes når javaskript tolkes og kjøres generelt. Vi har da også den generelle metoden eval() som brukes til å interpretere tekst som javascript. Vi kunne ha skrevet følgende i eksempelet ovenfor:

var person=eval("("+T+")"));

stringify

stringify skal i prinsipp gjøre det motsatte av parse, den skal lage en (parsbar) tekstrepresentasjon av et objekt.

var personen={navn:"Ole",
   adresse:"Halden",
   alder:32
  }
T=JSON.stringify( personen);

gir oss: {"navn":"Ole","adresse":"Halden","alder":32}

formater

Anta følgende globale definisjoner:

var T1='{"navn":"Ole","adresse":"Halden","alder":"32"}';
var T2='{"navn":"Ole","adresse":"Halden","alder":32}';
var obj1={"navn":"Ole","adresse":"Halden","alder":32};
var obj2={navn:"Ole",adresse:"Halden",alder:32};

Følgende metoder vil fungere og vise 32:

function test1(){
	var ob=JSON.parse(T1);
	alert(ob.alder);
}
function test2(){
	var ob=JSON.parse(T2);
	alert(ob.alder);
}
function test3(){
	alert(obj1.alder);
}
function test4(){
	alert(obj2.alder);
}

Følgende vil ikke fungere:

var T3='{navn:"Ole",adresse:"Halden",alder:32}';
function test5(){
	var ob=JSON.parse(T3);
	alert(ob.alder);
}

og feilmeldingen er som følger:"SyntaxError: JSON.parse: expected property name or '}'"

Det er noen vanlige fallgruver når vi skal produsere json, typisk når vi lager json-formatet i kode på tjeneren:

  • Vi går i vas med parenteser {}. Dette blir tydeligere i eksemplene nedenfor.
  • Vi legger inn data som inneholder ". JSON.parse() tolker " som innramming av en attributt-navn eller en verdi. Vi kan komme oss rundt dette med å escape med \\".
    {"navn":"Ole \\"the kid\\"","adresse":"Halden"}

Json siden, json.org [1] , refererer en rekke json biblioteker for andre språk, og det er flere on-line evalueringssider for json, f.eks. JSONLint [2] og Json Parser Online [3] .

funksjoner

Hva med funksjoner ? Kan vi på noen måte ta vare på disse. Vi vet at vi kan lage og bruke følgende objekt;

var person={navn:"Ole",
	   adresse:"Halden",
	   alder:32, 
	   visMeg:function(){return this.navn+' fra '+this.adresse;}
	  }
function test6(){
	alert( person.visMeg() );
	}

Hvis vi skal ivareta funksjoner i JSON-formatet må de lagres som string (merk at vi har skrevet \' for'):

var pT='{"navn":"Ole",+
         "adresse":"Halden",+
         "alder":32,+
         "visMeg":"function(){return this.navn+\' fra \'+this.adresse;}"}';

Nå vi så parser denne stringen vil vi få funksjonen som, nettopp, en string. For at den skal kunne brukes som funksjon må den evalueres

function test8(){
	var p=JSON.parse(pT);
	p.visMeg=eval("("+p.visMeg+")");
	alert( p.visMeg() );
}

Vi trenger selvsagt ikke legge funksjonene i JSON. Vi kan legge til de funksjonene vi ønsker når vi har parset stringen og fått opprettet et objekt.

Hvis vi har et objekt med en funksjon og parser denne

var person={navn:"Ole",
	   adresse:"Halden",
	   alder:32, 
	   visMeg:function(){return this.navn+' fra '+this.adresse;}
	  }
function test7(){
	alert( JSON.stringify(person) );
}

får vi: '{"navn":"Ole","adresse":"Halden","alder":32}'. Det vil si at funksjonen er ignorert.

Hvis vi er i den situasjon at vi har lastet opp objekter og vil tilordne dem funksjonalitet må vi gjøre dette eksplisitt. F.eks. slik:

var Tp='{"navn":"Ole","adresse":"Halden","alder":32}';
function test8(){
	var person2=JSON.parse(Tp);
	person2.visMeg=function(){return this.navn+' fra '+this.adresse;}
	alert( person2.visMeg() );
	}

lister

Vi kan lage lister, arrays, av objekter:

var T='{"personer":[{"navn":"Ole","adresse":"Halden"},{"navn":"Jens","adresse":"Moss"}]}'
var obj=JSON.parse(T);
var person= obj.personer;
alert(person[1].navn);	

Vi kan nøye oss med å konstatere at vi kan pakke attributter i objekter ved å angi "attributtnavn":"attributtverdi". Vi kan lage en kommaseparert liste av slike par. Videre ser vi at vi kan lage arrays med [].

Anta følgende JavaScript:

var DATA='{"personer":[{"navn":"Ole","adresse":"Halden"},{"navn":"Jens","adresse":"Moss"}]}';
var obj=null;
var personer=null;

function extractNames(){
    if(obj==null){
        obj=JSON.parse(DATA);
        personer=obj.personer;
    }
    var s='';
    for(ix=0;ix<personer.length;ix++){
        s+=personer[ix].navn+'\n';
    }
    document.getElementById("resultdump").innerHTML=s;
}
function changeandmakeJson(){
    if(obj==null){
        obj=JSON.parse(DATA);
        personer=obj.personer;
    }
    personer[0].navn="kristoffer";
    newObj={}
    newObj.personer=personer;
    s=JSON.stringify(newObj);
    document.getElementById("resultdump").innerHTML=s;
}

test funksjonene her:


			
Referanser
  1. JSON (JavaScript Object Notation) json.org www.json.org/ 02-02-2014
  1. JSONLint arc90 jsonlint.com/ 02-11-2012
  1. Json Parser Online json.parser.online.fr/ 02-11-2012