Rectangle 27 235

HTML5 defines a method for creating deep clones of objects. It only works for certain built-in types, but is considerably more flexible than using JSON. The internal structured cloning algorithm also supports an increasing number of types including Dates, RegExps, Maps, Sets, Blobs, FileLists, ImageDatas, sparse Arrays, and Typed Arrays, and supports cyclical/recursive structures.

There's no public API specifically for creating structured clones, but posting messages through MessageChannels is a pretty direct approach for asynchronous cloning. Here's one possible ES6 structuredClone(obj) function returning a Promise with a structured clone of obj.

class StructuredCloner {
  constructor() {
    this.pendingClones_ = new Map();
    this.nextKey_ = 0;

    const channel = new MessageChannel();
    this.inPort_ = channel.port1;
    this.outPort_ = channel.port2;

    this.outPort_.onmessage = ({data: {key, value}}) => {
      const resolve = this.pendingClones_.get(key);
      resolve(value);
      this.pendingClones_.delete(key);
    };
    this.outPort_.start();
  }

  clone(value) {
    return new Promise(resolve => {
      const key = this.nextKey_++;
      this.pendingClones_.set(key, resolve);
      this.inPort_.postMessage({key, value});
    });
  }
}

const structuredClone = window.structuredClone =
    StructuredCloner.prototype.clone.bind(new StructuredCloner);

Unfortunately, there are no good options for creating structured clones synchronously. The idea of adding a built-in structuredClone(...) function has been discussed several times and proposed here, but no browser vendors have taken action. Here are a couple of impractical hacks instead.

history.pushState() and history.replaceState() both create a structured clone of their first argument, and assign that value to history.state. You can use this to create a structured clone of any object like this:

Though synchronous, this can be extremely slow. It incurs all of the overhead associated with manipulating the browser history. Calling this method repeatedly can cause Chrome to become temporarily unresponsive.

The Notification constructor creates a structured clone of its associated data. It also attempts to display a browser notification to the user, but this will silently fail unless you have requested notification permission. In case you have the permission for other purposes, we'll immediately close the notification we've created.

const structuredClone = obj => {
  const n = new Notification('', {data: obj, silent: true});
  n.onshow = n.close.bind(n);
  return n.data;
};
'use strict';

const main = () => {
  const original = { date: new Date(), number: Math.random() };
  original.self = original;

  const clone = structuredClone(original);
  
  // They're different objects:
  console.assert(original !== clone);
  console.assert(original.date !== clone.date);

  // They're cyclical:
  console.assert(original.self === original);
  console.assert(clone.self === clone);

  // They contain equivalent values:
  console.assert(original.number === clone.number);
  console.assert(Number(original.date) === Number(clone.date));
  
  console.log("Assertions complete.");
};

const structuredClone = obj => {
  const n = new Notification('', {data: obj, silent: true});
  n.close();
  return n.data;
};

main();

@rynah I just looked through the spec again and you're right: the history.pushState() and history.replaceState() methods both synchronously set history.state to a structured clone of their first argument. A little weird, but it works. I'm updating my answer now.

As the guy who implemented pushState in Firefox, I feel an odd mix of pride and revulsion at this hack. Well done, guys.

What is the most efficient way to deep clone an object in JavaScript? ...

javascript object clone
Rectangle 27 228

HTML5 defines a method for creating deep clones of objects. It only works for certain built-in types, but is considerably more flexible than using JSON. The internal structured cloning algorithm also supports an increasing number of types including Dates, RegExps, Maps, Sets, Blobs, FileLists, ImageDatas, sparse Arrays, and Typed Arrays, and supports cyclical/recursive structures.

There's no public API specifically for creating structured clones, but posting messages through MessageChannels is a pretty direct approach for asynchronous cloning. Here's one possible ES6 structuredClone(obj) function returning a Promise with a structured clone of obj.

class StructuredCloner {
  constructor() {
    this.pendingClones_ = new Map();
    this.nextKey_ = 0;

    const channel = new MessageChannel();
    this.inPort_ = channel.port1;
    this.outPort_ = channel.port2;

    this.outPort_.onmessage = ({data: {key, value}}) => {
      const resolve = this.pendingClones_.get(key);
      resolve(value);
      this.pendingClones_.delete(key);
    };
    this.outPort_.start();
  }

  clone(value) {
    return new Promise(resolve => {
      const key = this.nextKey_++;
      this.pendingClones_.set(key, resolve);
      this.inPort_.postMessage({key, value});
    });
  }
}

const structuredClone = window.structuredClone =
    StructuredCloner.prototype.clone.bind(new StructuredCloner);

Unfortunately, there are no good options for creating structured clones synchronously. The idea of adding a built-in structuredClone(...) function has been discussed several times and proposed here, but no browser vendors have taken action. Here are a couple of impractical hacks instead.

history.pushState() and history.replaceState() both create a structured clone of their first argument, and assign that value to history.state. You can use this to create a structured clone of any object like this:

Though synchronous, this can be extremely slow. It incurs all of the overhead associated with manipulating the browser history. Calling this method repeatedly can cause Chrome to become temporarily unresponsive.

The Notification constructor creates a structured clone of its associated data. It also attempts to display a browser notification to the user, but this will silently fail unless you have requested notification permission. In case you have the permission for other purposes, we'll immediately close the notification we've created.

const structuredClone = obj => {
  const n = new Notification('', {data: obj, silent: true});
  n.onshow = n.close.bind(n);
  return n.data;
};
'use strict';

const main = () => {
  const original = { date: new Date(), number: Math.random() };
  original.self = original;

  const clone = structuredClone(original);
  
  // They're different objects:
  console.assert(original !== clone);
  console.assert(original.date !== clone.date);

  // They're cyclical:
  console.assert(original.self === original);
  console.assert(clone.self === clone);

  // They contain equivalent values:
  console.assert(original.number === clone.number);
  console.assert(Number(original.date) === Number(clone.date));
  
  console.log("Assertions complete.");
};

const structuredClone = obj => {
  const n = new Notification('', {data: obj, silent: true});
  n.close();
  return n.data;
};

main();

@rynah I just looked through the spec again and you're right: the history.pushState() and history.replaceState() methods both synchronously set history.state to a structured clone of their first argument. A little weird, but it works. I'm updating my answer now.

As the guy who implemented pushState in Firefox, I feel an odd mix of pride and revulsion at this hack. Well done, guys.

What is the most efficient way to deep clone an object in JavaScript? ...

javascript object clone
Rectangle 27 228

HTML5 defines a method for creating deep clones of objects. It only works for certain built-in types, but is considerably more flexible than using JSON. The internal structured cloning algorithm also supports an increasing number of types including Dates, RegExps, Maps, Sets, Blobs, FileLists, ImageDatas, sparse Arrays, and Typed Arrays, and supports cyclical/recursive structures.

There's no public API specifically for creating structured clones, but posting messages through MessageChannels is a pretty direct approach for asynchronous cloning. Here's one possible ES6 structuredClone(obj) function returning a Promise with a structured clone of obj.

class StructuredCloner {
  constructor() {
    this.pendingClones_ = new Map();
    this.nextKey_ = 0;

    const channel = new MessageChannel();
    this.inPort_ = channel.port1;
    this.outPort_ = channel.port2;

    this.outPort_.onmessage = ({data: {key, value}}) => {
      const resolve = this.pendingClones_.get(key);
      resolve(value);
      this.pendingClones_.delete(key);
    };
    this.outPort_.start();
  }

  clone(value) {
    return new Promise(resolve => {
      const key = this.nextKey_++;
      this.pendingClones_.set(key, resolve);
      this.inPort_.postMessage({key, value});
    });
  }
}

const structuredClone = window.structuredClone =
    StructuredCloner.prototype.clone.bind(new StructuredCloner);

Unfortunately, there are no good options for creating structured clones synchronously. The idea of adding a built-in structuredClone(...) function has been discussed several times and proposed here, but no browser vendors have taken action. Here are a couple of impractical hacks instead.

history.pushState() and history.replaceState() both create a structured clone of their first argument, and assign that value to history.state. You can use this to create a structured clone of any object like this:

Though synchronous, this can be extremely slow. It incurs all of the overhead associated with manipulating the browser history. Calling this method repeatedly can cause Chrome to become temporarily unresponsive.

The Notification constructor creates a structured clone of its associated data. It also attempts to display a browser notification to the user, but this will silently fail unless you have requested notification permission. In case you have the permission for other purposes, we'll immediately close the notification we've created.

const structuredClone = obj => {
  const n = new Notification('', {data: obj, silent: true});
  n.onshow = n.close.bind(n);
  return n.data;
};
'use strict';

const main = () => {
  const original = { date: new Date(), number: Math.random() };
  original.self = original;

  const clone = structuredClone(original);
  
  // They're different objects:
  console.assert(original !== clone);
  console.assert(original.date !== clone.date);

  // They're cyclical:
  console.assert(original.self === original);
  console.assert(clone.self === clone);

  // They contain equivalent values:
  console.assert(original.number === clone.number);
  console.assert(Number(original.date) === Number(clone.date));
  
  console.log("Assertions complete.");
};

const structuredClone = obj => {
  const n = new Notification('', {data: obj, silent: true});
  n.close();
  return n.data;
};

main();

@rynah I just looked through the spec again and you're right: the history.pushState() and history.replaceState() methods both synchronously set history.state to a structured clone of their first argument. A little weird, but it works. I'm updating my answer now.

As the guy who implemented pushState in Firefox, I feel an odd mix of pride and revulsion at this hack. Well done, guys.

What is the most efficient way to deep clone an object in JavaScript? ...

javascript object clone
Rectangle 27 227

HTML5 defines a method for creating deep clones of objects. It only works for certain built-in types, but is considerably more flexible than using JSON. The internal structured cloning algorithm also supports an increasing number of types including Dates, RegExps, Maps, Sets, Blobs, FileLists, ImageDatas, sparse Arrays, and Typed Arrays, and supports cyclical/recursive structures.

There's no public API specifically for creating structured clones, but posting messages through MessageChannels is a pretty direct approach for asynchronous cloning. Here's one possible ES6 structuredClone(obj) function returning a Promise with a structured clone of obj.

class StructuredCloner {
  constructor() {
    this.pendingClones_ = new Map();
    this.nextKey_ = 0;

    const channel = new MessageChannel();
    this.inPort_ = channel.port1;
    this.outPort_ = channel.port2;

    this.outPort_.onmessage = ({data: {key, value}}) => {
      const resolve = this.pendingClones_.get(key);
      resolve(value);
      this.pendingClones_.delete(key);
    };
    this.outPort_.start();
  }

  clone(value) {
    return new Promise(resolve => {
      const key = this.nextKey_++;
      this.pendingClones_.set(key, resolve);
      this.inPort_.postMessage({key, value});
    });
  }
}

const structuredClone = window.structuredClone =
    StructuredCloner.prototype.clone.bind(new StructuredCloner);

Unfortunately, there are no good options for creating structured clones synchronously. The idea of adding a built-in structuredClone(...) function has been discussed several times and proposed here, but no browser vendors have taken action. Here are a couple of impractical hacks instead.

history.pushState() and history.replaceState() both create a structured clone of their first argument, and assign that value to history.state. You can use this to create a structured clone of any object like this:

Though synchronous, this can be extremely slow. It incurs all of the overhead associated with manipulating the browser history. Calling this method repeatedly can cause Chrome to become temporarily unresponsive.

The Notification constructor creates a structured clone of its associated data. It also attempts to display a browser notification to the user, but this will silently fail unless you have requested notification permission. In case you have the permission for other purposes, we'll immediately close the notification we've created.

const structuredClone = obj => {
  const n = new Notification('', {data: obj, silent: true});
  n.onshow = n.close.bind(n);
  return n.data;
};
'use strict';

const main = () => {
  const original = { date: new Date(), number: Math.random() };
  original.self = original;

  const clone = structuredClone(original);
  
  // They're different objects:
  console.assert(original !== clone);
  console.assert(original.date !== clone.date);

  // They're cyclical:
  console.assert(original.self === original);
  console.assert(clone.self === clone);

  // They contain equivalent values:
  console.assert(original.number === clone.number);
  console.assert(Number(original.date) === Number(clone.date));
  
  console.log("Assertions complete.");
};

const structuredClone = obj => {
  const n = new Notification('', {data: obj, silent: true});
  n.close();
  return n.data;
};

main();

@rynah I just looked through the spec again and you're right: the history.pushState() and history.replaceState() methods both synchronously set history.state to a structured clone of their first argument. A little weird, but it works. I'm updating my answer now.

As the guy who implemented pushState in Firefox, I feel an odd mix of pride and revulsion at this hack. Well done, guys.

What is the most efficient way to deep clone an object in JavaScript? ...

javascript object clone
Rectangle 27 226

HTML5 defines a method for creating deep clones of objects. It only works for certain built-in types, but is considerably more flexible than using JSON. The internal structured cloning algorithm also supports an increasing number of types including Dates, RegExps, Maps, Sets, Blobs, FileLists, ImageDatas, sparse Arrays, and Typed Arrays, and supports cyclical/recursive structures.

There's no public API specifically for creating structured clones, but posting messages through MessageChannels is a pretty direct approach for asynchronous cloning. Here's one possible ES6 structuredClone(obj) function returning a Promise with a structured clone of obj.

class StructuredCloner {
  constructor() {
    this.pendingClones_ = new Map();
    this.nextKey_ = 0;

    const channel = new MessageChannel();
    this.inPort_ = channel.port1;
    this.outPort_ = channel.port2;

    this.outPort_.onmessage = ({data: {key, value}}) => {
      const resolve = this.pendingClones_.get(key);
      resolve(value);
      this.pendingClones_.delete(key);
    };
    this.outPort_.start();
  }

  clone(value) {
    return new Promise(resolve => {
      const key = this.nextKey_++;
      this.pendingClones_.set(key, resolve);
      this.inPort_.postMessage({key, value});
    });
  }
}

const structuredClone = window.structuredClone =
    StructuredCloner.prototype.clone.bind(new StructuredCloner);

Unfortunately, there are no good options for creating structured clones synchronously. The idea of adding a built-in structuredClone(...) function has been discussed several times and proposed here, but no browser vendors have taken action. Here are a couple of impractical hacks instead.

history.pushState() and history.replaceState() both create a structured clone of their first argument, and assign that value to history.state. You can use this to create a structured clone of any object like this:

Though synchronous, this can be extremely slow. It incurs all of the overhead associated with manipulating the browser history. Calling this method repeatedly can cause Chrome to become temporarily unresponsive.

The Notification constructor creates a structured clone of its associated data. It also attempts to display a browser notification to the user, but this will silently fail unless you have requested notification permission. In case you have the permission for other purposes, we'll immediately close the notification we've created.

const structuredClone = obj => {
  const n = new Notification('', {data: obj, silent: true});
  n.onshow = n.close.bind(n);
  return n.data;
};
'use strict';

const main = () => {
  const original = { date: new Date(), number: Math.random() };
  original.self = original;

  const clone = structuredClone(original);
  
  // They're different objects:
  console.assert(original !== clone);
  console.assert(original.date !== clone.date);

  // They're cyclical:
  console.assert(original.self === original);
  console.assert(clone.self === clone);

  // They contain equivalent values:
  console.assert(original.number === clone.number);
  console.assert(Number(original.date) === Number(clone.date));
  
  console.log("Assertions complete.");
};

const structuredClone = obj => {
  const n = new Notification('', {data: obj, silent: true});
  n.close();
  return n.data;
};

main();

@rynah I just looked through the spec again and you're right: the history.pushState() and history.replaceState() methods both synchronously set history.state to a structured clone of their first argument. A little weird, but it works. I'm updating my answer now.

As the guy who implemented pushState in Firefox, I feel an odd mix of pride and revulsion at this hack. Well done, guys.

What is the most efficient way to deep clone an object in JavaScript? ...

javascript object clone
Rectangle 27 11

You don't want to stringify large objects into a single localStorage entry. That would be very inefficient - the whole thing would have to be parsed and re-encoded every time some slight detail changes. Also, JSON can't handle multiple cross references within an object structure and wipes out a lot of details, e.g. the constructor, non-numerical properties of arrays, what's in a sparse entry, etc.

Instead, you can use http://rhaboo.org. It stores large objects using lots of localStorage entries so you can make small changes quickly. The restored objects are much more accurate copies of the saved ones and the API is incredibly simple. E.g.:

var store = Rhaboo.persistent('Some name');
store.write('count', store.count ? store.count+1 : 1);
store.write('somethingfancy', {
  one: ['man', 'went'],
  2: 'mow',
  went: [  2, { mow: ['a', 'meadow' ] }, {}  ]
});
store.somethingfancy.went[1].mow.write(1, 'lawn');

Thanks Martin. You might as well check my 'evon' repo as well. It's only a serialiser right now and the ink is very wet, but it's faster than rhaboo and equally versatile. Rhaboo will soon be converted to use it internally.

Useful but I don't think this addresses the question "What is the max size of localStorage;" your answer could be improved by stating what happens when this library tries to store something beyond the size limit, and how to react to it.

javascript - What is the max size of localStorage values? - Stack Over...

javascript html5 local-storage
Rectangle 27 11

You don't want to stringify large objects into a single localStorage entry. That would be very inefficient - the whole thing would have to be parsed and re-encoded every time some slight detail changes. Also, JSON can't handle multiple cross references within an object structure and wipes out a lot of details, e.g. the constructor, non-numerical properties of arrays, what's in a sparse entry, etc.

Instead, you can use http://rhaboo.org. It stores large objects using lots of localStorage entries so you can make small changes quickly. The restored objects are much more accurate copies of the saved ones and the API is incredibly simple. E.g.:

var store = Rhaboo.persistent('Some name');
store.write('count', store.count ? store.count+1 : 1);
store.write('somethingfancy', {
  one: ['man', 'went'],
  2: 'mow',
  went: [  2, { mow: ['a', 'meadow' ] }, {}  ]
});
store.somethingfancy.went[1].mow.write(1, 'lawn');

Thanks Martin. You might as well check my 'evon' repo as well. It's only a serialiser right now and the ink is very wet, but it's faster than rhaboo and equally versatile. Rhaboo will soon be converted to use it internally.

Useful but I don't think this addresses the question "What is the max size of localStorage;" your answer could be improved by stating what happens when this library tries to store something beyond the size limit, and how to react to it.

javascript - What is the max size of localStorage values? - Stack Over...

javascript html5 local-storage
Rectangle 27 11

You don't want to stringify large objects into a single localStorage entry. That would be very inefficient - the whole thing would have to be parsed and re-encoded every time some slight detail changes. Also, JSON can't handle multiple cross references within an object structure and wipes out a lot of details, e.g. the constructor, non-numerical properties of arrays, what's in a sparse entry, etc.

Instead, you can use http://rhaboo.org. It stores large objects using lots of localStorage entries so you can make small changes quickly. The restored objects are much more accurate copies of the saved ones and the API is incredibly simple. E.g.:

var store = Rhaboo.persistent('Some name');
store.write('count', store.count ? store.count+1 : 1);
store.write('somethingfancy', {
  one: ['man', 'went'],
  2: 'mow',
  went: [  2, { mow: ['a', 'meadow' ] }, {}  ]
});
store.somethingfancy.went[1].mow.write(1, 'lawn');

Thanks Martin. You might as well check my 'evon' repo as well. It's only a serialiser right now and the ink is very wet, but it's faster than rhaboo and equally versatile. Rhaboo will soon be converted to use it internally.

Useful but I don't think this addresses the question "What is the max size of localStorage;" your answer could be improved by stating what happens when this library tries to store something beyond the size limit, and how to react to it.

javascript - What is the max size of localStorage values? - Stack Over...

javascript html5 local-storage
Rectangle 27 1

From your post that looks correct to me, I am somewhat new to JSON myself but it looks like its treating the last key-value pair as an array, to access the individual elements you would have to use the correct index to access the value. from json.org JSON is built on two structures: A collection of name/value pairs. In various languages, this is realized as an object, record, struct, dictionary, hash table, keyed list, or associative array. An ordered list of values. In most languages, this is realized as an array, vector, list, or sequence. you could check it on jsonlint.com if you still think something is wrong.

javascript - sending a post request with json data that contains a lis...

javascript jquery ajax json post
Rectangle 27 1

From your post that looks correct to me, I am somewhat new to JSON myself but it looks like its treating the last key-value pair as an array, to access the individual elements you would have to use the correct index to access the value. from json.org JSON is built on two structures: A collection of name/value pairs. In various languages, this is realized as an object, record, struct, dictionary, hash table, keyed list, or associative array. An ordered list of values. In most languages, this is realized as an array, vector, list, or sequence. you could check it on jsonlint.com if you still think something is wrong.

javascript - sending a post request with json data that contains a lis...

javascript jquery ajax json post
Rectangle 27 1

Depending on the size/structure of your object containing the arrays, you can simply iterate over they keys and find the key whose value (array) contains the value you are looking for. Here's how it would look.

var $arrays = {
  "greeting": ['hello', 'hi'],
  "food": ['pizza', 'cookie']
};
var x = 'hi',
    y = 'pizza';

function getContainerName(value) {
  return Object.keys($arrays).find(function(key) {
    return $arrays[key].find(function(elem) {
      return elem === value;
    })
  });
}

console.log(getContainerName(x));
console.log(getContainerName(y));

Alternatively in ES6 syntax

return Object.keys($arrays).find(key => $arrays[key].find(elem => elem === value));
.every()
y = ['chips', 'pizza'], x = {"food":['banana', 'carrot', 'pizza', 'wheat', 'chips']};

function getContainerName(obj, values) {
  return Object.keys(obj).find(function(key) {
    return values.every(value => obj[key].find(function(elem) {
      return elem === value;
    }));
  });
}

console.log(getContainerName(x, y));
y = ['chips', 'pizza'], x = {"food":['banana', 'carrot', 'pizza', 'wheat', 'chips']}
console.log(getContainerName(x))
food

Awesome, last thing, I tried modifying it for there to be more than just food in the array, and added greetings, but I get undefined error when I change pizza in y to hi. jsfiddle.net/u1zLm71f

@Ackados Well, that changes the problem more than you might think. You should open up a new question and I can answer it there.

arrays - Get json string name from json variables using javascript/jqu...

javascript arrays json
Rectangle 27 50

No. Order is not guaranteed in JSON and most other key-value data structures, so therefore the last item could sometimes be carrot and at other times be banana and so on. If you need to rely on ordering, your best bet is to go with arrays. The power of key-value data structures lies in accessing values by their keys, not in being able to get the nth item of the object.

As an expansion on this entirely correct answer. Objects are not arrays, even if you create an associative array in JS using the array markers [] it is really an object. JS does not have associative arrays as such, arrays have indexed access and sequence; objects have associative property access, non-sequential.

I know they aren't guaranteed to have an order, but if I have control over the object's creation, in practical terms, I can make sure they're in an specific order. Clearly, the answer to the question, though, is "no". :)

@sprugman: Not in Chrome. A long a heated debate has been raging about this subject: code.google.com/p/v8/issues/detail?id=164

getting the last item in a javascript object - Stack Overflow

javascript object
Rectangle 27 1

No. The structure you've quoted is an object with property names like "2015-02-28". Objects in JavaScript have no order to their properties at all. To have order, you must (for now) have an array. ES6 will introduce Map objects, which are maps ordered by the insertion order of their keys. But ES5 doesn't have those.

That doesn't mean you can't access those properties in any order you want. You can get an array of the property names via Object.keys, and you can sort arrays however you like.

Sort date property in object in ascending order Angularjs/Javascript -...

javascript angularjs
Rectangle 27 0

As I said in the comments, you can use a simple reviver function within the JSON parsing, as long as you keep the keys in mind. See this jsFiddle: http://jsfiddle.net/38Ytc/3/ This is an example, let's suppose you got the JSON string somewhere (in the example, from a textbox), and you need to add certain functions to the objects returned by this data. We then call parse with an reviver function as the second argument, that will be called for each key within the data structure. For our minimal example, it would convert all non-array objects except the top level object (key "") to a DataRow object, which has the methods get, set and save.

After this processing, you could simply use resultObject.entries.object[0].get("title") to get a object's title, if it exists.

javascript - Add prototype to all objects in a JSON string - Stack Ove...

javascript json inheritance prototype
Rectangle 27 0

<?php


// get the json

$data = file_get_contents( 'http://url_to_the_json' );


// decode the json

$data = json_decode( $data );


// see it

echo '<pre>' . print_r( $data, true ) . '</pre>';


// data is now a php object/array/combination.
// I'm not sure how your json file is structured but you can try:

echo $data->registry->name;

Thanks! That worked. Any way of only printing name?

javascript - Extract JSON data and embed in HTML - Stack Overflow

javascript php html json
Rectangle 27 0

You don't want to stringify large objects into a single localStorage entry. That would be very inefficient - the whole thing would have to be parsed and re-encoded every time some slight detail changes. Also, JSON can't handle multiple cross references within an object structure and wipes out a lot of details, e.g. the constructor, non-numerical properties of arrays, what's in a sparse entry, etc.

Instead, you can use http://rhaboo.org. It stores large objects using lots of localStorage entries so you can make small changes quickly. The restored objects are much more accurate copies of the saved ones and the API is incredibly simple. E.g.:

var store = Rhaboo.persistent('Some name');
store.write('count', store.count ? store.count+1 : 1);
store.write('somethingfancy', {
  one: ['man', 'went'],
  2: 'mow',
  went: [  2, { mow: ['a', 'meadow' ] }, {}  ]
});
store.somethingfancy.went[1].mow.write(1, 'lawn');

Thanks Martin. You might as well check my 'evon' repo as well. It's only a serialiser right now and the ink is very wet, but it's faster than rhaboo and equally versatile. Rhaboo will soon be converted to use it internally.

Useful but I don't think this addresses the question "What is the max size of localStorage;" your answer could be improved by stating what happens when this library tries to store something beyond the size limit, and how to react to it.

javascript - What is the max size of localStorage values? - Stack Over...

javascript html5 local-storage
Rectangle 27 0

Example Usage (jsfiddle)

HTML5 defines a method to create deep clones of objects. It still only works for certain built-in types, but it's more flexible than using JSON. The internal structured clone algorithm also supports Dates, RegExps, Files, Blobs, FileLists, ImageDatas, sparse Arrays, types defined in other specification such as Typed Arrays, and recursive/cyclical structures.

This feature is not yet directly exposed through any API. Below I describe two ways of creating structured clones through other APIs that use them. They both incur overhead that makes them many times slower than using a straightforward JSON copy. A more direct API may be made available in the future.

history.pushState() and history.replaceState() both create a structured clone of their first argument, and assign that value to history.state. You can use this to create a structured clone of any object like this:

function structuredClone_replaceState(obj) {
    var oldState = history.state;
    history.replaceState(obj, null);
    var clonedObj = history.state;
    history.replaceState(oldState, null);
    return clonedObj;
}

Though synchronous, this can be is extremely slow. It incurs all of the overhead associated with manipulating the browser history. Calling this method repeatedly can cause Chrome to become temporarily unresponsive.

Calling window.postMessage(original) triggers an message event on window with a .data property whose value is a structured clone of the original. Here's function which uses this behaviour to asynchronously produce a structured clone of a target object and pass it to your callback.

var pendingCallbacks = {};

window.addEventListener('message', function(e) {
    var cloneId = e.data.cloneId,
        clonedValue = e.data.value;

    if (e.source === window && cloneId != null && cloneId in pendingCallbacks) {
        var callback = pendingCallbacks[cloneId];
        delete pendingCallbacks[cloneId];
        callback(clonedValue);
    }
});

var asyncStructuredClone_windowPostMessage = function(o, callback) {
    var cloneId = asyncStructuredClone_windowPostMessage.nextCloneId_++;
    pendingCallbacks[cloneId] = callback;
    window.postMessage({ value: o, cloneId: cloneId }, '*');
};
asyncStructuredClone_windowPostMessage.nextCloneId_ = 0;
var original = { date: new Date(), number: Math.random() };
original.self = original;

asyncStructuredClone_windowPostMessage(original, function(clone) {
    // They're different objects:
    console.log(original !== clone);
    console.log(original.date !== clone.date);

    // They're cyclical:
    console.log(original.self === original);
    console.log(clone.self === clone);

    // They contain equivalent values:
    console.log(original.number === clone.number);
    console.log(Number(original.date) === Number(clone.date));
});

It's possible to do this in a more isolated manner using a new MessageChannel instead of the global window, but so far that's only been implemented in Chrome.

@rynah I just looked through the spec again and you're right: the history.pushState() and history.replaceState() methods both synchronously set history.state to a structured clone of their first argument. A little weird, but it works. I'm updating my answer now.

As the guy who implemented pushState in Firefox, I feel an odd mix of pride and revulsion at this hack. Well done, guys.

javascript - What is the most efficient way to clone an object? - Stac...

javascript object clone
Rectangle 27 0

As I already mentioned in the comments, if you can make certain assumptions about the values of the objects, you could use a regular expression to replace the keys, for example:

str = str.replace(/"title":/g, '"name":');

It's not as "clean", but it might get the job done faster.

If you have to parse the JSON anyway, a more structured approach would be to pass a reviver function to JSON.parse and you might be able to avoid an additional pass over the array. This probably depends on how engine implement JSON.parse though (maybe they parse the whole string first and then make a second pass with the reviver function, in which case you wouldn't get any advantage).

var arr = JSON.parse(str, function(prop, value) {
   switch(prop) {
     case "title":
        this.name = value;
        return;
     case "uid":
        this.id = value;
        return;
     default:
        return value;
   }
});

Benchmarks, using the Node.js script below to test 3 times:

1389822740739: Beginning regex rename test
1389822740761: Regex rename complete
// 22ms, 22ms, 21ms
1389822740762: Beginning parse and remap in for loop test
1389822740831: For loop remap complete
// 69ms, 68ms, 68ms
1389822740831: Beginning reviver function test
1389822740893: Reviver function complete
// 62ms, 61ms, 60ms

Test script, loading 100,230 lines of the OP's sample JSON:

fs = require('fs');
fs.readFile('test.json', 'utf8', function (err, data) {
    if (err) {
        return console.log(err);
    }
    console.log(new Date().getTime() + ": Beginning regex rename test");
    var str = data.replace(/"title":/g, '"name":');
    str = str.replace(/"uid":/g, '"id":');
    JSON.parse(str);
    console.log(new Date().getTime() + ": Regex rename complete");
    console.log(new Date().getTime() + ": Beginning parse and remap in for loop test");
    var arr = JSON.parse(data);
    for (var i = 0; i < arr.length; i++) {
        arr[i].name = arr[i].title;
        arr[i].id = arr[i].uid;
        delete arr[i].title;
        delete arr[i].uid;
    }
    console.log(new Date().getTime() + ": For loop remap complete");
    console.log(new Date().getTime() + ": Beginning reviver function test");
    var arr = JSON.parse(data, function (prop, value) {
        switch (prop) {
            case "title":
                this.name = value;
                return;
            case "uid":
                this.id = value;
                return;
            default:
                return value;
        }
    });
    console.log(new Date().getTime() + ": Reviver function complete");
});

Still looks like the regex is the quickest -- I'm only testing this in a simple Node.js instance, I can update your answer with the benchmarks if you like?

@remus: Yep, that would be cool! Sorry, I don't have the time now to make those tests myself.

OK, updated. Hope you don't mind I hijacked it like that, but there's a wealth of information there now.

Awesome! Nice to see that the reviver function is at least a little faster (though not by much). And yeah, you have to be careful with regular expressions and be certain about the input you get.

Luckily in my case I'm using consistent data with a consistent schema, so it won't be a problem. And also in my case, since I need this to server thousands of requests in Node, I want it to be as efficient as possible. Thanks!

Efficiently rename/re-map javascript/json object keys within structure...

javascript arrays json javascript-objects
Rectangle 27 0

If you don't know about the keys of an object, but need all keys present within an it, you can use Object.keys():

var b,a,d1,d2,d3, i, keys;
for (b = 0 , a = ty_tabs.length; b < a ; ++b){
    keys = Object.keys( ty_tabs[b] );

    for( i=0; i<keys.length; i++ ) {
      d1 = ty_tabs[b][ keys[i] ][0].d1;
      d2 = ty_tabs[b][ keys[i] ][0].d2;
      d3 = ty_tabs[b][ keys[i] ][0].d3;
    }
}
Object.keys()

javascript - how to get name array as object dynamic for values - Stac...

javascript arrays json object
Rectangle 27 0

var arr = [
{"id":1, "name":"Sport", "parent_id":0, "children":[]},
{"id":2, "name":"Tennis", "parent_id":4, "children":[]},
{"id":3, "name":"Climbing", "parent_id":5, "children":[]},
{"id":4, "name":"Indoor", "parent_id":1, "children":[]},
{"id":5, "name":"Outdoor", "parent_id":1, "children":[]},
{"id":6, "name":"Bowling", "parent_id":4, "children":[]}
]

var i = 0, len = arr.length, item, parent, id, key, treeArr = {};

for (; i < len; i++) {
    item = arr[i];
    parent = item.parent_id;
    id = item.id;

    if (treeArr[id] == undefined) {
       treeArr[id] = item;   
    } else if (typeof treeArr[id] == 'object') {
        for (key in item) {
            if (key == 'children') continue;
            treeArr[id][key] = item[key];   
        }        
    }

    if (typeof treeArr[parent] != 'object') {
        treeArr[parent] = { children: [] };   
    }

    treeArr[parent].children.push(treeArr[id]);
}

console.log(treeArr[0]);

javascript - Reorder a JS object in a child-parent structure - Stack O...

javascript jquery arrays json