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.
Related
1) In some other languages define function as parameterized block of statements, and on syntactic level javascript function also looks like this, until it's said that it can have it's own properties and methods.How can it be syntactically represented as key/value pair? And where does function code live?
var x = function(a,b){alert('Hi');};
// x = { _code: "alert('Hi'), _arguments: {a:.., b:..,}}
here code and arguments are my imaginary internal properties
2) If array is key/value pair, can i think that array indexes are just object keys?
var a = ["elem1", "elem2"];
// a = {0: "elem1", 1: "elem2"}
Expanding on my comment that EVERYTHING in JavaScript is a object.
var arr = [
function () {
console.log("Well... Look at that.");
}
];
var obj = arr[0];
obj();
var newObj = Object.assign({}, arr);
console.log(newObj);
newObj[0]();
How can it be syntactically represented as key/value pair?
It can't.
The executable code of a function is not expressed in terms of properties on an object.
And where does function code live?
That's an implementation detail of the JavaScript engine, not something that is exposed to JavaScript code in a standard way.
If array is key/value pair, can i think that array indexes are just object keys?
They are just properties. See the specification:
Array objects give special treatment to a certain class of property names. A property name P (in the form of a String value) is an array index if and only if ToString(ToUint32(P)) is equal to P and ToUint32(P) is not equal to 232−1. A property whose property name is an array index is also called an element. Every Array object has a length property whose value is always a nonnegative integer less than 232. The value of the length property is numerically greater than the name of every property whose name is an array index;
… and so on.
I saw this for the first time (or noticed it for the first time) today during a maintenance of a colleagues code.
Essentially the "weird" part is the same as if you try to run this code:
var arr = [];
arr[0] = "cat"; // this adds to the array
arr[1] = "mouse"; // this adds to the array
arr.length; // returns 2
arr["favoriteFood"] = "pizza"; // this DOES NOT add to the array. Setting a string parameter adds to the underlying object
arr.length; // returns 2, not 3
Got this example from nfiredly.com
I don't know what the technical term for this "case" is so I haven't been able to find any additional information about it here or on Google but it strikes me very peculiar that this "behaviour" can at all exists in JavaScript; a kind of "mix" between Arrays and Objects (or Associative Arrays).
It states in the above code snippet that that Setting a string parameter adds to the underlying object and thus not affect the length of the "array" itself.
What is this kind of pattern?
Why is it at all possible? Is it a weird JS quirk or is it deliberate?
For what purpose would you "mix" these types?
It's possible because arrays are objects with some special behaviors, but objects nevertheless.
15.4 Array Objects
However, if you start using non-array properties on an array, some implementations may change the underlying data structure to a hash. Then array operations might be slower.
In JavaScript, arrays, functions and objects are all objects. Arrays are objects created with Array constructor function.
E.g.
var a = new Array();
Or, using shortcut array literal,
var a = [];
Both are the same. They both create objects. However, special kind of object. It has a length property and numeric properties with corresponding values which are the array elements.
This object (array) has methods like push, pop etc. which you can use to manipulate the object.
When you add a non-numeric property to this array object, you do not affect its length. But, you do add a new property to the object.
So, if you have
var a = [1];
a.x = 'y';
console.log(Object.keys(a)); // outputs ["0", "x"]
console.log(a); // outputs [1];
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'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
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.