In JavaScript's JSON.stringify() function, I occasionally see the following syntax:
JSON.stringify(obj, null, 4)
However, I can't get what the second argument, null, is supposed to do. As long as I know, the above function takes an object as its first argument, and converts it to a string variable. The third argument, 4 in this case, indents and pretty-prints the resultant string object. But I can't see what the second argument tries to do even after I read the explanation on the official document... So what does the argument do? Or is it just there in order to take in the third argument? (But I think then the function should take both argument name and its parameter, such that for example, JSON.stringify(obj, space=4). I'm not sure whether that sort of syntax is allowed in JavaScript, so forgive me if it's not. But I don't know my expectation is correct in the first place, so would like to throw a question anyway).
Thanks.
The second parameter can be a function to perform replacement while stringifying.
A null or undefined second parameter means that you want to use standard
stringification, without any customization.
From https://developer.mozilla.org/en-US/docs/Using_native_JSON#The_replacer_pa
Starting in Firefox 3.5.4, JSON.stringify() offers additional
customization capabilities through the use of optional parameters. The
syntax is:
jsonString = JSON.stringify(value [, replacer [, space]])
value The JavaScript object to convert into a JSON string.
replacer A function that alters the behavior of the stringification process, or
an array of String and Number objects that serve as a whitelist for
selecting the properties of the value object to be included in the
JSON string. If this value is null or not provided, all properties of
the object are included in the resulting JSON string.
space A String or Number object that's used to insert white space into the output
JSON string for readability purposes. If this is a Number, it
indicates the number of space characters to use as white space; this
number is capped at 10 if it's larger than that. Values less than 1
indicate that no space should be used. If this is a String, the string
(or the first 10 characters of the string, if it's longer than that)
is used as white space. If this parameter is not provided (or is
null), no white space is used. The replacer parameter
The replacer parameter can be either a function or an array. As a
function, it takes two parameters, the key and the value being
stringified. The object in which the key was found is provided as the
replacer's this parameter. Initially it gets called with an empty key
representing the object being stringified, and it then gets called for
each property on the object or array being stringified. It should
return the value that should be added to the JSON string, as follows:
If you return a Number, the string corresponding to that number is
used as the value for the property when added to the JSON string. If
you return a String, that string is used as the property's value when
adding it to the JSON string. If you return a Boolean, "true" or
"false" is used as the property's value, as appropriate, when adding
it to the JSON string. If you return any other object, the object is
recursively stringified into the JSON string, calling the replacer
function on each property, unless the object is a function, in which
case nothing is added to the JSON string. If you return undefined, the
property is not included in the output JSON string. Note: You cannot
use the replacer function to remove values from an array. If you
return undefined or a function then null is used instead.
Example
function censor(key, value) {
if (typeof(value) == "string") {
return undefined;
}
return value;
}
var foo = {foundation: "Mozilla",
model: "box",
week: 45,
transport: "car",
month: 7};
var jsonString = JSON.stringify(foo, censor);
The resulting JSON string is {"week":45,"month":7}.
If replacer is an array, the array's values indicate the names of the
properties in the object that should be included in the resulting JSON
string.
There is no way to pass third parameter without passing second parameter in JavaScript.
So null is a placeholder for replacer function when you need to pass space.
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/JSON/stringify
JSON.stringify(value[, replacer[, space]])
replacer A function that alters the behavior of the stringification process, or an array of String and Number objects that serve as a whitelist for selecting/filtering the properties of the value object to be included in the JSON string. If this value is null or not provided, all properties of the object are included in the resulting JSON string.
The replacer parameter can be either a function or an array.
As a function, it takes two parameters: the key and the value being stringified. The object in which the key was found is provided as the replacer's this parameter.
Initially, the replacer function is called with an empty string as key representing the object being stringified. It is then called for each property on the object or array being stringified.
Related
The JSON.stringify() method converts a JavaScript value to a JSON
console.log(JSON.stringify('a'));
//produce "a"
console.log(JSON.stringify(1));
//produce 1
console.log(JSON.stringify(true));
//produce true
but according to the definition these are not JSON
"a"
1
true
JSON definition is showing below
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.
my question is JSON.stringify() not producing JSON when input above values why is that ?
The JSON.stringify() method converts a JavaScript value to a JSON
string, optionally replacing values if a replacer function is
specified, or optionally including only the specified properties if a
replacer array is specified.
Ref: https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/JSON/stringify
"my question is JSON.stringify() not producing JSON when input above values why is that?"
These are all Valid JSON syntax representing JSON value:
"a"
1
true
{}
[]
Check this:
JSON.parse('"foo"'); // returns "foo"
JSON.parse(1); // returns 1
JSON.parse(true); // returns true
JSON.parse('{}'); // returns {}
JSON.parse('[]'); // returns []
For more clarification this check these answers:
Is this simple string considered valid JSON?
What is the minimum valid JSON?
The following two lines produce the following output:
console.log('arr:'+arr);
console.log('inspected arr:'+util.inspect(arr));
arr:,testUser2
inspected arr:[ null, 'testUser2' ]
is it because it starts with a null value? it is very confusing that it doesn't even show up as an array.
it is in fact an array though!
That is because you have null in array and when you say
"somestring" + array
it converts array to string using toString(), so null will be converted to "".
just try in browser console [null,1,2].toString() it will print ",1,2".
While Util.inspect returns a proper string representation of the object. Where it will print every thing as string something like JSON.stringify().
JS's occasionally-wat coercion rules.
Once you coerce it to a string the brackets go away, and a null value is represented by zero characters. inspect is the proper way to specify you want it to print out it's "natural" representation.
Well, the empty string when you try to print out the array if the value is null in the array is right as per specification in ECMAScript here
when you try to concat the array like that, actually what you do is that you implicitly call the toString function in the array object which will call the join function in array object. And, in join spec, the function should check the null value, if null then it should return empty string.
This is taken from documentation.
If element0 is undefined or null, let R be the empty String; otherwise, let R be ToString(element0).
in your case, I guess it will be much better to use util.inspect() as it does print more "pretty" information.
I'm currently reading 'Singe Page Web Applications' book. I encountered the following example:
// This is single pass encoder for html entities and handles
// an arbitrary number of characters
encodeHtml = function ( input_arg_str, exclude_amp) {
var input_str = String( input_arg_str), regex, lookup_map;
...
return input_str.replace(regex, function ( match, name ){
return lookup_map[ match ] || '';
});
};
I wonder, what is the purpose of using function String() with argument input_arg_str. I know that by using String() function I can convert different object to string, but I never met with such a feature using String().
I'm curious what you think about this and top thank you for your help.
#Amit Joki's answer is correct, of course, but there are several ways you could convert an object to a string, why use String(...)?
I'd guess the main reason here is that it safely handle's null and undefined whereas .toString would obviously fail.
String(undefined) // "undefined"
String(null) // "null"
In short, it's a more defensive way to convert an object to a string than .toString. Here's a note about it on MDN:
It's possible to use String as a "safer" toString alternative, as
although it still normally calls the underlying toString, it also
works for null and undefined.
I believe you get the same results with string concatenation:
var input_str = '' + input_arg_str; // also handles `null` and `undefined`
Can't say I've ever found a reason to use it, but MDN does suggest there are some subtle differences between string literals and string objects (emphasis mine):
Note that JavaScript distinguishes between String objects and primitive string values. (The same is true of Boolean 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.
String primitives and String objects also give different results when using eval. Primitives passed to eval are treated as source code; String objects are treated as all other objects are, by returning the object.
For these reasons, code may break when it encounters String objects when it expects a primitive string instead, although generally authors need not worry about the distinction.
source: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String
As others have said, in the context of the code you posted, it does ensure that whatever was passed as input_arg_str is converted to an actual string.
I have flash application, which creates array and calls javascript function.
var jsParams = ["3011","3012","3013","3014","3015"];
ExternalInterface.call("doCall", jsParams);
And this is my javascript function:
function doCall(params) {
console.log(params);
console.log(params[0]);
}
The output in the firebug is:
["3011","3012","3013","3014","3015"]
[
But for the second line i was expecting 3011 and not [. Then i have tried to call same function with same params from firebug and the function outputed:
doCall(["3011","3012","3013","3014","3015"]);
["3011","3012","3013","3014","3015"]
3011
My question is how to pass params from actionscript to javascript as array and not as string value.
Thanks.
It looks like the params variable is being passed in as a string, rather than an array.
Square bracket notation, when applied to a string, represents the character at the supplied index, which in this case would be the '[' (position 0).
You should look into JSON decoding to find a safe way to convert the string back into an array , I wouldn't recommend eval, and JSON.decode isn't widely supported.
have you tried encapsulating the array within another array?
ExternalInterface.call("doCall", [jsParams]);
I think a initial array is so you can pass mulitple sets of parameters
I want to understand the basic differences clearly between Javascript object and JSON string.
Let's say I create the following JS variable:
var testObject = {one: 1,"two":2,"three":3};
Q1. Is the key/property name valid both with/without quotes? (e.g. "one" : 1)
If yes, what is the difference?
Q2: If I convert the above object using JSON.stringify(testObject), what’s the difference between the original JS object and the JSON?
I feel they are almost the same. Please elaborate on this.
Q3: For parsing a JSON string, is the method below recommended?
var javascriptObj = JSON.parse(jSonString);
Is the key/property name valid both with/without quotes ?
The only time you need to enclose a key in quotes when using Object Literal notation is where the key is a reserved word or contains a special character (if, :, - etc). It is worth noting that a key in JSON must be enclosed in double quotes.
If I convert the above object to JSON using var jSonString = JSON.stringify(testObject);, what is the difference between the 2 (JS obj and JSON)?
JSON is a data interchange format. It's a standard which describes how ordered lists and unordered maps, strings, booleans and numbers can be represented in a string. Just like XML and YAML is a way to pass structured information between languages, JSON is the same. A JavaScript object on the other hand is a physical type. Just like a PHP array, a C++ class/ struct, a JavaScript object is a type internal to JavaScript.
Here's a story. Let's imagine you've purchased some furniture from a store, and you want it delivered. However the only one left in stock is the display model, but you agree to buy it.
In the shop, the chest-of-drawers you've purchased is a living object:
var chestOfDrawers = {
color: "red",
numberOfDrawers: 4
}
However, you can't send a chest-of-drawers in the post, so you dismantle it (read, stringify it). It's now useless in terms of furniture. It is now JSON. Its in flat pack form.
{"color":"red","numberOfDrawers":4}
When you receive it, you then rebuild the chest-of-drawers (read, parse it). Its now back in object form.
The reason behind JSON, XML and YAML is to enable data to be transferred between programming languages in a format both participating languages can understand; you can't give PHP or C++ your JavaScript object directly; because each language represents an object differently under-the-hood. However, because we've stringified the object into JSON notation; i.e. a standardised way to represent data, we can transmit the JSON representation of the object to another language (C++, PHP), they can recreate the JavaScript object we had into their own object based on the JSON representation of the object.
It is important to note that JSON cannot represent functions or dates. If you attempt to stringify an object with a function member, the function will be omitted from the JSON representation. A date will be converted to a string;
JSON.stringify({
foo: new Date(),
blah: function () {
alert('hello');
}
}); // returns the string "{"foo":"2011-11-28T10:21:33.939Z"}"
For parsing a JSON string, is the method below recommended? var javascriptObj = JSON.parse(jSonString);
Yes, but older browsers don't support JSON natively (IE <8). To support these, you should include json2.js.
If you're using jQuery, you can call jQuery.parseJSON(), which will use JSON.parse() under the hood if it's supported and will otherwise fallback to a custom implementation to parse the input.
Q1: When defining object literals in javascript, the keys may include quotes or not. There is no difference except that quotes allow you to specify certain keys that would cause the interpreter to fail to parse if you tried them bare. For example, if you wanted a key that was just an exclamation point, you would need quotes:
a = { "!": 1234 } // Valid
a = { !: 1234 } // Syntax error
In most cases though, you can omit the quotes around keys on object literals.
Q2: JSON is literally a string representation. It is just a string. So, consider this:
var testObject = { hello: "world" }
var jSonString = JSON.stringify(testObject);
Since testObject is a real object, you can call properties on it and do anything else you can do with objects:
testObject.hello => "world"
On the other hand, jsonString is just a string:
jsonString.hello => undefined
Note one other difference: In JSON, all keys must be quoted. That contrasts with object literals, where the quotes can usually be omitted as per my explanation in Q1.
Q3. You can parse a JSON string by using JSON.parse, and this is generally the best way to do it (if the browser or a framework provides it). You can also just use eval since JSON is valid javascript code, but the former method is recommended for a number of reasons (eval has a lot of nasty problems associated with it).
Problems solved by JSON
Let's say you want to exchange regular JavaScript objects between two computers, and you set two rules:
The transmitted data must be a regular string.
Only attributes can be exchanged, methods are not transmitted.
Now you create two objects on the first host:
var obj1 = { one: 1,"two":2,"three":3 }; // your example
var obj2 = { one: obj1.one, two: 2, three: obj1.one + obj1.two };
How can you convert those objects into strings for transmission to the second host?
For the first object, you could send this string obtained form the literal definition '{ one: 1,"two":2,"three":3 }', but actually you can't read the literal in the script portion of the document (at least not easily). So obj1 and obj2 must actually be processed the same way.
You need to enumerate all attributes and their value, and build a string similar to the object literal.
JSON has been created as a solution to the needs just discussed: It is a set of rules to create a string equivalent to an object by listing all attributes and values (methods are ignored).
JSON normalizes the use of double-quotes for attribute names and values.
Remember that JSON is a set of rules only (a standard).
How many JSON objects are created?
Only one, it is automatically created by the JS engine.
Modern JavaScript engines found in browsers have a native object, also named JSON. This JSON object is able to:
Decode a string built using JSON standard, using JSON.parse(string). The result is a regular JS object with attributes and values found in the JSON string.
Encode attributes / values of a regular JS object using JSON.stringify(). The result is a string compliant with the JSON set of rules.
The (single) JSON object is similar to a codec, it's function is to encode and decode.
Note that:
JSON.parse() doesn't create a JSON object, it creates a regular JS object, there is no difference between an object created using an object literal and an object created by JSON.parse() from a JSON-compliant string.
There is only one JSON object, which is used for all conversions.
Going back to the questions:
Q1: The use of single of double quotes is allowed for object literals. Note that the quotes are used optionally for attributes names, and are mandatory for string values. The object literal itself is not surrounded by quotes.
Q2: Objects created from literals and using JSON.parse() are strictly the same. These two objects are equivalent after creation:
var obj1 = { one: 1, "two": 2, "three": 3 };
var obj2 = JSON.parse('{ "one": "1", "two": "2", "three": "3" }');
Q3: On modern browsers JSON.parse() is used to create a JS object from a JSON-compliant string. (jQuery has also an equivalent method that can be used for all browsers).
Q1 - in JS you only need to use quotes if the key is a reserved word or if it would otherwise be an illegal token. In JSON you MUST always use double quotes on key names.
Q2 - the jsonString is a serialised version of the input object ...
Q3 - which may be deserialised to an identical looking object using JSON.parse()
Question already has good answers posted, I am adding a small example below, which will make it more easy to understand the explanations given in previous answers.
Copy paste below snippet to your IDE for better understanding and comment the
line containing invalid_javascript_object_no_quotes object declaration to avoid compile time error.
// Valid JSON strings(Observe quotes)
valid_json = '{"key":"value"}'
valid_json_2 = '{"key 1":"value 1"}' // Observe the space(special character) in key - still valid
//Valid Javascript object
valid_javascript_object_no_quotes = {
key: "value" //No special character in key, hence it is valid without quotes for key
}
//Valid Javascript object
valid_javascript_object_quotes = {
key:"value", //No special character in key, hence it is valid without quotes for key
"key 1": "value 1" // Space (special character) present in key, therefore key must be contained in double quotes - Valid
}
console.log(typeof valid_json) // string
console.log(typeof valid_javascript_object_no_quotes) // object
console.log(typeof valid_javascript_object_quotes) // object
//Invalid Javascript object
invalid_javascript_object_no_quotes = {
key 1: "value"//Space (special character) present in key, since key is not enclosed with double quotes "Invalid Javascript Object"
}