This question already has answers here:
What is the difference between JSON and Object Literal Notation?
(10 answers)
Closed 4 years ago.
I am new to JSON and JavaScript objects.
Can someone please explain the differences between JSON and JavaScript object?
What are their uses?
Is one better than the other? Or does it depend on the situation?
When to use which one, in what situation?
Why was JSON created in the first place? What was its main purpose?
Can someone give examples of when one should use JSON rather than a JavaScript object and vice versa?
First you should know what JSON is:
It is language agnostic data-interchange format.
The syntax of JSON was inspired by the JavaScript Object Literal notation, but there are differences between them.
For example, in JSON all keys must be quoted, while in object literals this is not necessary:
// JSON:
{ "foo": "bar" }
// Object literal:
var o = { foo: "bar" };
The quotes are mandatory on JSON because in JavaScript (more exactly in ECMAScript 3rd. Edition), the usage of reserved words as property names is disallowed, for example:
var o = { if: "foo" }; // SyntaxError in ES3
While, using a string literal as a property name (quoting the property name) gives no problems:
var o = { "if": "foo" };
So for "compatibility" (and easy eval'ing maybe?) the quotes are mandatory.
The data types in JSON are also restricted to the following values:
string
number
object
array
A literal as:
true
false
null
The grammar of Strings changes. They have to be delimited by double quotes, while in JavaScript, you can use single or double quotes interchangeably.
// Invalid JSON:
{ "foo": 'bar' }
The accepted JSON grammar of Numbers also changes, in JavaScript you can use Hexadecimal Literals, for example 0xFF, or (the infamous) Octal Literals e.g. 010. In JSON you can use only Decimal Literals.
// Invalid JSON:
{ "foo": 0xFF }
There are some buggy implementations (Firefox 3.5+, IE8+, json2.js) where octal literals are wrongly allowed, e.g. JSON.parse('01') should produce a SyntaxError.
JSON is a string representation of an object. It is an interoperable serialization format. It is not tied only to javascript. For example there are JSON serializers for .NET allowing you to serialize/deserialize .NET objects.
So it's just a format allowing you to convert from objects to string and back which is convenient if you want to transfer them over the wire.
It is very close to javascript object representation and if you simply eval() a JSON string you will get the corresponding object.
JSON is a data interchange format, which just happens to look like a subset of YAML or JavaScript code you can execute and get an object back. A JavaScript object is just an object in JavaScript.
With JSON being a data interchange format you can exchange structured data in a textual form with it. It is pretty decoupled from JavaScript by now. JavaScript object allow you to create and work with structured data during the execution of a JavaScript program.
Related
This question already has answers here:
Are JavaScript strings immutable? Do I need a "string builder" in JavaScript?
(10 answers)
Closed 2 years ago.
This code does not work
var x ='hello';
x[2] ='a';
Why doesn't it work?
I am not using the replace() function
In javascript the strings are immutable, you cannot change the string using index.
The string manipulation methods such as trim, slice return new strings.
It doesn't work because of legacy behavior of promoting string values to String object wrappers with the value of the primitive string value.
So for example
"xyz".charAt(0)
is at least notionally evaluated as
(new String("xyz")).charAt(0)
because charAt is a prototype method of String objects and can be applied to a primitive string value in this manner.
The down side is that the promoted String object is never stored anywhere and, even if modified in JavaScript is immediately discarded. This is what is happening in the code posted:
var x ='hello';
x[2] ='a';
is treated as
new String(x)[2] = 'a'
followed by discarding the String object which, incidentally, has a property named 2 with value 'a'.
The general solution to this is to run JavaScript in strict mode, so that any attempt to assign a property to a primitive value which has been promoted to an object wrapper generates an error:
"use strict"
var x ='hello';
x[2] ='a';
In Kyle Simpson's book You Don't Know JS: this & Object Prototypes, he writes this on the subject of how to duplicate an object:
One subset solution is that objects which are JSON-safe (that is, can be serialized to a JSON string and then re-parsed to an object with the same structure and values) can easily be duplicated with:
var newObj = JSON.parse( JSON.stringify( someObj ) );
Of course, that requires you to ensure your object is JSON safe. For some situations, that's trivial. For others, it's insufficient.
What is a "JSON-safe" object? I ran a few tests with JavaScript and so far most things (arrays, numbers, strings, objects) can be duplicated using the above line, except for methods (foo.bar), when trying to duplicate a method, undefined is inserted in the method's place in the duplicated object.
To get foo<=> JSON.parse(JSON.stringify(foo)) as true, we must be able to represent foo in the JSON format.
JSON only supports:
Number: a signed decimal number that may contain a fractional part and may use exponential E notation, but cannot include non-numbers like NaN. The format makes no distinction between integer and floating-point. JavaScript uses a double-precision floating-point format for all its numeric values, but other languages implementing JSON may encode numbers differently.
String: a sequence of zero or more Unicodecharacters. Strings are delimited with double-quotation marks and support a backslash escaping syntax.
Boolean: either of the values true or false
Array: an ordered list of zero or more values, each of which may be of any type. Arrays use square bracket notation with elements being comma-separated.
Object: an unordered collection of name/value pairs where the names (also called keys) are strings. Since objects are intended to represent associative arrays,[12] it is recommended, though not required,[13] that each key is unique within an object. Objects are delimited with curly brackets and use commas to separate each pair, while within each pair the colon ':' character separates the key or name from its value.
null: An empty value, using the word null
In javascript, the concept of JSON safe object basically refers to a javascript object that can be represented in the JSON format without any loss.
I have an object with the following key:
*_data
However, the characters are encoded in a non-standard format that is causing my code some problems.
I saved the value of the key to a cookie, and found the following:
%00*%00_data
However, when comparing this string (using == not ===) with the value of the key, they are not equal.
Currently I am storing the key's value into a variable and using that variable as the key. However, I'm extremely curious as to what string I could compare the actual key with that would result in true.
Any help with this mystery would be greatly appreciated.
%00 is the URI-encoded UTF-8 representation of the character NUL, representing the null character. I imagine this is used here to differentiate between the actual * character and a * character which may be replaced by some library you're using.
We can get from %00*%00_data to *_data by using JavaScript's decideURIComponent() method, which, as the name suggests, decodes the URI-encoded character:
decodeURIComponent("%00*%00_data");
Based on your comments, it seems that the key variable you're comparing against is actually this string of length 8. I mention this, because the string *_data you've included in your question is of length 6, as it doesn't include the two null characters.
I have recently seen some references that explain Strings in Javascript as a primitive type.I know that a primitive is a data type that is composed of no other data types and can not be broken down any further.But the problem is I have also read strings are objects.How it can be both ?Please clarify me about the confusion.
You can read about that exact topic on MDN:
Note that JavaScript distinguishes between String objects and
primitive string values. (The same is true of booleans and numbers.)
String literals (denoted by double or single quotes) and strings
returned from String calls in a non-constructor context (i.e., without
using the new keyword) are primitive strings. JavaScript automatically
converts primitives to String objects, so that it's possible to use
String object methods for primitive strings. In contexts where a
method is to be invoked on a primitive string or a property lookup
occurs, JavaScript will automatically wrap the string primitive and
call the method or perform the property lookup.
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String
I've read in some places that JavaScript strings are UTF-16, and in other places they're UCS-2. I did some searching around to try to figure out the difference and found this:
Q: What is the difference between UCS-2 and UTF-16?
A: UCS-2 is obsolete terminology which refers to a Unicode
implementation up to Unicode 1.1, before surrogate code points and
UTF-16 were added to Version 2.0 of the standard. This term should now
be avoided.
UCS-2 does not define a distinct data format, because UTF-16 and UCS-2
are identical for purposes of data exchange. Both are 16-bit, and have
exactly the same code unit representation.
Sometimes in the past an implementation has been labeled "UCS-2" to
indicate that it does not support supplementary characters and doesn't
interpret pairs of surrogate code points as characters. Such an
implementation would not handle processing of character properties,
code point boundaries, collation, etc. for supplementary characters.
via: http://www.unicode.org/faq/utf_bom.html#utf16-11
So my question is, is it because the JavaScript string object's methods and indexes act on 16-bit data values instead of characters what make some people consider it UCS-2? And if so, would a JavaScript string object oriented around characters instead of 16-bit data chunks be considered UTF-16? Or is there something else I'm missing?
Edit: As requested, here are some sources saying JavaScript strings are UCS-2:
http://blog.mozilla.com/nnethercote/2011/07/01/faster-javascript-parsing/
http://terenceyim.wordpress.com/tag/ucs2/
EDIT: For anyone who may come across this, be sure to check out this link:
http://mathiasbynens.be/notes/javascript-encoding
JavaScript, strictly speaking, ECMAScript, pre-dates Unicode 2.0, so in some cases you may find references to UCS-2 simply because that was correct at the time the reference was written. Can you point us to specific citations of JavaScript being "UCS-2"?
Specifications for ECMAScript versions 3 and 5 at least both explicitly declare a String to be a collection of unsigned 16-bit integers and that if those integer values are meant to represent textual data, then they are UTF-16 code units. See
section 8.4 of the ECMAScript Language Specification in version 5.1
or section 6.1.4 in version 13.0.
EDIT: I'm no longer sure my answer is entirely correct. See the excellent article mentioned above, which in essence says that while a JavaScript engine may use UTF-16 internally, and most do, the language itself effectively exposes those characters as if they were UCS-2.
It's UTF-16/USC-2. It can handle surrogate pairs, but the charAt/charCodeAt returns a 16-bit char and not the Unicode codepoint. If you want to have it handle surrogate pairs, I suggest a quick read through this.
Its just a 16-bit value with no encoding specified in the ECMAScript standard.
See section 7.8.4 String Literals in this document: http://www.ecma-international.org/publications/files/ECMA-ST/Ecma-262.pdf
Things have changed since 2012. JavaScript strings are now UTF-16 for real. Yes, the old string methods still work on 16-bit code units, but the language is now aware of UTF-16 surrogates and knows what to do about them if you use the string iterator. There's also Unicode regex support.
// Before
"😀😂💩".length // 6
// Now
[..."😀😂💩"].length // 3
[..."😀😂💩"] // [ '😀', '😂', '💩' ]
[... "😀😂💩".matchAll(/./ug) ] // 3 matches as above
// Regexes support unicode character classes
"café".normalize("NFD").match(/\p{L}\p{M}/ug) // [ 'é' ]
// Extract code points
[..."😀😂💩"].map(char => char.codePointAt(0).toString(16)) // [ '1f600', '1f602', '1f4a9' ]