I was trying to stringify an array-like object that was declared as an array object and found that JSON.stringify wasn't processing correctly array-like object when it is defined as an array object.
See below for more clarity, --> jsFiddle
var simpleArray = []; //note that it is defined as Array Object
alert(typeof simpleArray); // returns object -> Array Object
simpleArray ['test1'] = 'test 1';
simpleArray ['test2'] = 'test 2';
alert(JSON.stringify(simpleArray)); //returns []
It worked fine and returned me {"test1":"test 1","test2":"test 2"} when I changed
var simpleArray = []; to var simpleArray = {};.
Can someone shed some light or some reference where I can read more?
Edit:
Question: When typeof simpleArray = [] and simpleArray = {} returned object, why JSON.stringify wasn't able to return {"test1":"test 1","test2":"test 2"} in both cases?
The difference is the indexes. When you use an array [] the indexes can only be positive integers.
So the following is wrong:
var array = [ ];
array['test1'] = 'test 1';
array['test2'] = 'test 2';
because test1 and test2 are not integers. In order to fix it you need to use integer based indexes:
var array = [ ];
array[0] = 'test 1';
array[1] = 'test 2';
or if you declare a javascript object then the properties can be any strings:
var array = { };
array['test1'] = 'test 1';
array['test2'] = 'test 2';
which is equivalent to:
var array = { };
array.test1 = 'test 1';
array.test2 = 'test 2';
You don't want an array. When you want an "associative array" in JavaScript, you really want an object, {}.
You can distinguish them with instanceof Array:
[] instanceof Array // true
({}) instanceof Array // false
EDIT: it can process it. It serializes all of the elements of the array. However, to be an element, there must be a numeric key. In this case, there are none.
This is nothing unique to JSON. It's consistent with toSource and the length property.
"Can someone shed some light or some reference where I can read more?"
When you're dealing with JSON data, you can refer to json.org to read about the requirements of the specification.
In JSON, an Array is an order list of values separated by ,.
So the JSON.stringify() is simply ignoring anything that couldn't be represented as a simple ordered list.
So if you do...
var simpleArray = [];
simpleArray.foo = 'bar';
...you're still giving an Array, so it is expecting only numeric indices, and ignoring anything else.
Because JSON is language independent, the methods for working with JSON need to make a decision about which language structure is the best fit for each JSON structure.
So JSON has the following structures...
{} // object
[] // array
You should note that though the look very similar to JavaScript objects and arrays, they're not strictly the same.
Any JavaScript structures used to create JSON structures must conform to what the JSON structures will allow. This is why the non-numeric properties are removed excluded.
While JavaScript doesn't mind them, JSON won't tolerate them.
When JSON.stringify encounters an array, it iterates in a similar way to a for loop from 0 to simpleArray.length to find the values. For example:
var a = [];
a[5] = "abc";
alert(JSON.stringify(a)); // alerts [null,null,null,null,null,"abc"]
Therefore setting properties on it will be completely invisible to JSON.
However defining the object with {} makes JSON treat it as an object, and therefore it loops over the object's properties (excluding inherited properties from the prototype chain). In this manner it can find your test1 and test2 properties, and successfully returns what you expect.
The differences between Array instances and other objects are specified in the ECMAScript Language Specification, Edition 5.1, section 15.4.
You will find there that while you can use the bracket property accessor syntax with all object references --
objRef[propertyName]
-- Array instances are special. Only using a parameter value which string representation is that of an unsigned 32-bit integer value less than 232-1 accesses an element of the encapsulated array structure, and write access affects the value of the Array instance's length property.
Section 15.12 specifies the JSON object and its stringify method accordingly.
In Javascript, everything is an object, so even Arrays.
This is why you get:
>> var l = [1, 2];
>> typeof l
"object"
Arrays are stored the same way as objects. So, in fact, arrays are only hashtable objects. The index you provide when accessing e.g.
>> l[0]
is not interpreted as an offset, but is hashed and then searched for.
So Arrays, are just objects (with some builtin array-methods) and so you can treat them like objects and put a value under a certain key.
But only those keys indexed by numbers are used to compute the length.
>> var l = []
>> l.length
0
>> l[5] = 1;
>> l.length
6
>> l
[undefined, undefined, undefined, undefined, undefined, 1]
>> l.hello = "Hello"
>> l.length
6
Read Array - MDN for more information
and Associative Arrays considered harmful why you should not do this.
Your code is not semantically correct, but because most JavaScript engines are really nice on the programmer they allow these types of mistakes.
A quick test case:
var a = [];
a.b = "c";
console.log(JSON.stringify(a));//yields [], and not {"b":"c"} as you might expect
This might be because of some strictness in JSON.stringify which still treats a like an Array.
I wouldn't worry about it overly much. This is a situation that should not occur in your program because it is an error. JSLint is a popular tool to catch these and many more potential problems in your code.
Related
In JavaScript, you can have objects, like this:
var a = { foo: 12, bar: 34 };
Or arrays with key (named) indexes, like this:
var b = [];
b['foo'] = 56;
b['bar'] = 78;
They're somewhat similar, but obviously not the same.
Now the strange thing is, JSON.stringify doesn't seem to take the array. No errors or anything, JSON.stringify(b) just results in [].
See this jsfiddle example. Am I doing something wrong, or do I just misunderstand how arrays work?
Javascript doesn't support Associative arrays (Like PHP).
var b = []; Declaring explicitly an array, when you are trying to create an Object.
Arrays in Javascript can only contain the Index approach of Arrays, while Objects are more of
Associative arrays.
If you change var b = []; to var b = {}; it will solve the problem.
var b = {} Declaring explicitly an Object.
Javascript arrays are objects. See https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Predefined_Core_Objects#Array_Object for details.
Note: if you supply a non-integer value to the array operator in the
code above, a property will be created in the object representing the
array, instead of an array element.
JSON supports only a subset of Javascript. See http://www.json.org/ for details.
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.
A Javascript array that has properties created in the underlying object does not fit into either of these structures because it has both a collection of name/value pairs and an ordered list of values, so there is no simple way to represent such an object directly in JSON.
The JSON.stringify method is defined in the ECMAScript specification. For example, see http://www.ecma-international.org/ecma-262/5.1/#sec-15.12.3.
While there are many details, the bit that is relevant here is how object values are stringified:
If Type(value) is Object, and IsCallable(value) is false
If the [[Class]] internal property of value is "Array" then Return the result of calling the abstract operation JA with argument value.
Else, return the result of calling the abstract operation JO with argument value.
Given your array, despite the addition of parameters to the underlying object, the result is of stringifying the ordered set of array elements, not the underlying object.
There is nothing wrong about adding parameters to an array object, but they are not part of the array and functions or methods that handle arrays might ignore them or deal with them arbitrarily. You have seen that JSON.stringify ignores the additional parameters. Other functions might do otherwise - you will have to find out in each case.
While it is not wrong, it will probably be easier to understand if you do not add properties to array objects. If you want to add properties, start with a non-array object.
Rather than:
var b = [];
b['foo'] = 56;
b['bar'] = 78;
You might use:
var b = {};
b['foo'] = 56;
b['bar'] = 78;
This snap is from IE explorer. See the array is still blank.
Actually the way of inserting the elements to the array is :
1. Use push()
2. insert the elements in the array during declaration
If you want to stringify the array you have to have the data inside the array.
So, now you want to stringify the key value pairs so you have to pass the object as the argument of JSON.stringify() as follows:
var test = {}; // Object
test['a'] = 'test';
test['b'] = []; // Array
test['b'].push('item');
test['b'].push('item2');
test['b'].push('item3');
var json = JSON.stringify(test);
alert(json);
Solution to your problem now:
Note: Console of Google Chrome is giving different result, which is a bug in Google Chrome.
What’s the difference between “{}” and “[]” while declaring a JavaScript array?
Normally I declare like
var a=[];
What is the meaning of declaring the array as var a={}
Nobody seems to be explaining the difference between an array and an object.
[] is declaring an array.
{} is declaring an object.
An array has all the features of an object with additional features (you can think of an array like a sub-class of an object) where additional methods and capabilities are added in the Array sub-class. In fact, typeof [] === "object" to further show you that an array is an object.
The additional features consist of a magic .length property that keeps track of the number of items in the array and a whole slew of methods for operating on the array such as .push(), .pop(), .slice(), .splice(), etc... You can see a list of array methods here.
An object gives you the ability to associate a property name with a value as in:
var x = {};
x.foo = 3;
x["whatever"] = 10;
console.log(x.foo); // shows 3
console.log(x.whatever); // shows 10
Object properties can be accessed either via the x.foo syntax or via the array-like syntax x["foo"]. The advantage of the latter syntax is that you can use a variable as the property name like x[myvar] and using the latter syntax, you can use property names that contain characters that Javascript won't allow in the x.foo syntax.
A property name can be any string value.
An array is an object so it has all the same capabilities of an object plus a bunch of additional features for managing an ordered, sequential list of numbered indexes starting from 0 and going up to some length. Arrays are typically used for an ordered list of items that are accessed by numerical index. And, because the array is ordered, there are lots of useful features to manage the order of the list .sort() or to add or remove things from the list.
When you declare
var a=[];
you are declaring a empty array.
But when you are declaring
var a={};
you are declaring a Object .
Although Array is also Object in Javascript but it is numeric key paired values.
Which have all the functionality of object but Added some few method of Array like Push,Splice,Length and so on.
So if you want Some values where you need to use numeric keys use Array.
else use object.
you can Create object like:
var a={name:"abc",age:"14"};
And can access values like
console.log(a.name);
var a = [];
it is use for brackets for an array of simple values.
eg.
var name=["a","b","c"]
var a={}
is use for value arrays and objects/properties also.
eg.
var programmer = { 'name':'special', 'url':'www.google.com'}
It can be understood like this:
var a= []; //creates a new empty array
var a= {}; //creates a new empty object
You can also understand that
var a = {}; is equivalent to var a= new Object();
Note:
You can use Arrays when you are bothered about the order of elements(of same type) in your collection else you can use objects. In objects the order is not guaranteed.
they are two different things..
[] is declaring an Array:
given, a list of elements held by numeric index.
{} is declaring a new object:
given, an object with fields with Names and type+value,
some like to think of it as "Associative Array".
but are not arrays, in their representation.
You can read more # This Article
Syntax of JSON
object = {} | { members }
members = pair | pair, members
pair = string : value
array = [] | [ elements ]
elements = value | value elements
value =
string|number|object|array|true|false|null
In JavaScript Arrays and Objects are actually very similar, although on the outside they can look a bit different.
For an array:
var array = [];
array[0] = "hello";
array[1] = 5498;
array[536] = new Date();
As you can see arrays in JavaScript can be sparse (valid indicies don't have to be consecutive) and they can contain any type of variable! That's pretty convenient.
But as we all know JavaScript is strange, so here are some weird bits:
array["0"] === "hello"; // This is true
array["hi"]; // undefined
array["hi"] = "weird"; // works but does not save any data to array
array["hi"]; // still undefined!
This is because everything in JavaScript is an Object (which is why you can also create an array using new Array()). As a result every index in an array is turned into a string and then stored in an object, so an array is just an object that doesn't allow anyone to store anything with a key that isn't a positive integer.
So what are Objects?
Objects in JavaScript are just like arrays but the "index" can be any string.
var object = {};
object[0] = "hello"; // OK
object["hi"] = "not weird"; // OK
You can even opt to not use the square brackets when working with objects!
console.log(object.hi); // Prints 'not weird'
object.hi = "overwriting 'not weird'";
You can go even further and define objects like so:
var newObject = {
a: 2,
};
newObject.a === 2; // true
[ ] - this is used whenever we are declaring an empty array,
{ } - this is used whenever we declare an empty object
typeof([ ]) //object
typeof({ }) //object
but if your run
[ ].constructor.name //Array
so from this, you will understand it is an array here Array is the name of the base class.
The JavaScript Array class is a global object that is used in the construction of arrays which are high-level, list-like objects.
I am working on javascript and I run into this:
if i do
let object = {};
object.length
It will complain that object.length is undefined
But
let object = [];
object.length
works
Any know why?
Thanks
In JavaScript, virtually everything is an object (there are exceptions however, most notably null and undefined) which means that nearly all values have properties and methods.
var str = 'Some String';
str.length // 11
{} is shorthand for creating an empty object. You can consider this as the base for other object types. Object provides the last link in the prototype chain that can be used by all other objects, such as an Array.
[] is shorthand for creating an empty array. While also a data structure similar to an object (in fact Object as mentioned previously is in its prototype chain), it is a special form of an object that stores sequences of values.
typeof [] // "object"
When an array is created it automatically has a special property added to it that will reflect the number of elements stored: length. This value is automatically updated by certain methods while also used by others.
var arr = [];
arr.hasOwnProperty('length'); // true
arr.length; // 0
In fact there is nothing special about properties on arrays (although there are few if any good reasons to use them) aside from the engine using them for those methods.
var arr = [];
arr.foo = 'hello';
arr // []
arr.foo // "hello"
arr.length // 0
This is not true of an Object though. It does not have a length property added to it as it does not expect a sequence of values. This is why when you try to access length the value returned is undefined which is the same for any unknown property.
var obj = {};
obj.hasOwnProperty('length'); // false
obj.length; // undefined
obj.foo; // undefined
So, basically an array is a special data structure that expects a sequence of data. Because of this a property is added automatically that represents the length of the data structure.
BONUS: You can use length to trim an array:
var a = [1,2,3,4,5];
a.length; // 5
a.length = 2;
a; // [1, 2]
a.length; // 2
This is because [] is an array object and the length is 0 because there are no elements. {} is an object and there is no property length. The array object does have a property called length, thats why you see the number of elements when you call [].length
[] signifies an array in javascript, so it has length. {} is just declaring an object.
They're different things. One is an object, another is an array.
{} is an object, which has keys and values.
You can't necessarily determine the length of an object since its key-value pairs may not necessarily be numbers or indexed in any way.
[] is an array, which has numbered indices. It's pretty straightforward it has a length.
In JavaScript, you can have objects, like this:
var a = { foo: 12, bar: 34 };
Or arrays with key (named) indexes, like this:
var b = [];
b['foo'] = 56;
b['bar'] = 78;
They're somewhat similar, but obviously not the same.
Now the strange thing is, JSON.stringify doesn't seem to take the array. No errors or anything, JSON.stringify(b) just results in [].
See this jsfiddle example. Am I doing something wrong, or do I just misunderstand how arrays work?
Javascript doesn't support Associative arrays (Like PHP).
var b = []; Declaring explicitly an array, when you are trying to create an Object.
Arrays in Javascript can only contain the Index approach of Arrays, while Objects are more of
Associative arrays.
If you change var b = []; to var b = {}; it will solve the problem.
var b = {} Declaring explicitly an Object.
Javascript arrays are objects. See https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Predefined_Core_Objects#Array_Object for details.
Note: if you supply a non-integer value to the array operator in the
code above, a property will be created in the object representing the
array, instead of an array element.
JSON supports only a subset of Javascript. See http://www.json.org/ for details.
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.
A Javascript array that has properties created in the underlying object does not fit into either of these structures because it has both a collection of name/value pairs and an ordered list of values, so there is no simple way to represent such an object directly in JSON.
The JSON.stringify method is defined in the ECMAScript specification. For example, see http://www.ecma-international.org/ecma-262/5.1/#sec-15.12.3.
While there are many details, the bit that is relevant here is how object values are stringified:
If Type(value) is Object, and IsCallable(value) is false
If the [[Class]] internal property of value is "Array" then Return the result of calling the abstract operation JA with argument value.
Else, return the result of calling the abstract operation JO with argument value.
Given your array, despite the addition of parameters to the underlying object, the result is of stringifying the ordered set of array elements, not the underlying object.
There is nothing wrong about adding parameters to an array object, but they are not part of the array and functions or methods that handle arrays might ignore them or deal with them arbitrarily. You have seen that JSON.stringify ignores the additional parameters. Other functions might do otherwise - you will have to find out in each case.
While it is not wrong, it will probably be easier to understand if you do not add properties to array objects. If you want to add properties, start with a non-array object.
Rather than:
var b = [];
b['foo'] = 56;
b['bar'] = 78;
You might use:
var b = {};
b['foo'] = 56;
b['bar'] = 78;
This snap is from IE explorer. See the array is still blank.
Actually the way of inserting the elements to the array is :
1. Use push()
2. insert the elements in the array during declaration
If you want to stringify the array you have to have the data inside the array.
So, now you want to stringify the key value pairs so you have to pass the object as the argument of JSON.stringify() as follows:
var test = {}; // Object
test['a'] = 'test';
test['b'] = []; // Array
test['b'].push('item');
test['b'].push('item2');
test['b'].push('item3');
var json = JSON.stringify(test);
alert(json);
Solution to your problem now:
Note: Console of Google Chrome is giving different result, which is a bug in Google Chrome.
I'm trying to learn javascript (coming from Delphi/pascal) and am unclear about the similarities and differences between object properties and array values. I did try searching the archives and the web for this answer.
Consider the following code:
function Show(Arr) {
var str ='';
for (var Val in Arr) {
str += Val + '::' + Arr[Val] + '\n';
}
return str;
}
var str = '';
var A1 = ["Yellow", "Red", "Blue"];
var A2 = {"color":"red", "Size": 5, "taste":"sour"}
alert(Show(A1));
//OUTPUTS:
// 0::Yellow
// 1::Red
// 2::Blue
A1.push("Green");
alert(Show(A1));
//OUTPUTS:
// 0::Yellow
// 1::Red
// 2::Blue
// 3::Green
alert('Length: '+A1.length);
//OUTPUTS:
// Length: 4
alert(Show(A2));
//OUTPUTS:
// color::red
// Size::5
// taste:sour
alert('Length: '+A2.length);
//OUTPUTS:
// Length: undefined
A2.push("Green");
//ERROR --> execution stops on jsfiddle.net.
alert("OK"); //<-- never executed
alert(Show(A2)); //<-- never executed
I know that almost everything is an object in javascript. I have been reading here (http://javascript.info/tutorial/objects) and here (http://www.w3schools.com/js/js_objects.asp).
I see that an array can be accessed by index, e.g. A1[3] --> Blue, as in other languages. But I see also that a property can be accessed this way, e.g. A2["Size"] --> 5. So at first blush, it looks like array values and property values are essentially the same. But arrays can be extended with a .push(value) command, whereas properties can't.
It is coincidence that my Show function works for both arrays and objects?
Actually, as I have written this and researched the topic, is it just that all arrays are objects, but not all objects are array? So then does the for...in loop in Show() actually work differently depending on which type of object is sent in?
Any help clarifying this would be appreciated. Thanks.
So at first blush, it looks like array values and property values are essentially the same.
Array entries and object properties are indeed the same thing, because JavaScript's standard arrays aren't really arrays at all, they're just objects with some added features. Two of those features are the special length property, and the push function, which is why you don't see those with A2.
Your observation about bracketed notation is particularly spot-on. In JavaScript, you can access object properties using bracketed notation and a string, like this:
var o = {answer: 42};
console.log(o['answer']); // 42
It's not well-known that this is exactly what you're doing when using an array "index":
var a = ['a', 'b', 'c'];
console.log(a[1]); // b
The 1 we're using with a[1], technically according to the specification, is coerced to a string (a["1"]), and then that property name is used to look up the property on the object.
So then does the for...in loop in Show() actually work differently depending on which type of object is sent in?
No, for-in works the same with all objects. It iterates the names of the enumerable properties of the object. Whether you're using an array or any other object doesn't matter.
Note that not all properties are enumerable. For instance, Array#length isn't, nor is Array#push or Object#toString or any of the other built-in properties of objects.
But for instance, you can see that for-in is the same for arrays as for other objects like this:
var a = ['zero']; // An array with one entry
a.answer = 42; // We've added a property to the object that isn't an array entry
console.log(a.length); // 1, because `length` only relates to array "indexes" as
// defined by the specification
var key;
for (key in a) {
console.log(key + "=" + value);
}
// Shows (in *no reliable order*):
// 0=zero
// answer=42
More about for-in:
Myths and realities of for..in (on my blog)
My answer to the question For each in array, how to do that in JavaScript? here on SO