Hello, I keep getting undefined when I run this piece of code - javascript

this is my code:
var a = 10;
for(var i = 0; i < a; i++){ document.write(a[i]); }
I have left the var empty but it still didn't work.

a[i] looks up the property whose name is the value of i on whatever's in a. What you have in a is the primitive number 10. When you try to get an object property from a primitive number, it gets temporarily promoted to the equivalent Number instance, and then the property is taken from that instance. (Loosely speaking.)
Your i has the vaules 0 through 9, so those are the names of the properties that get looked up. Numbers don't have properties with those names, and so you get what you always get when you try to retrieve a property that doesn't exist: undefined.

You attempt to subscript an integer variable is not going to work. Try using an array instead.
var a = [item1, item2, ...];
and then use a loop to iterate over individual item and display:
for (i = 0; i < a.length; i++) {
document.write(a[i]);
}

Related

JavaScript array with property

I was using array like this
var names=['a','b','c'];
when I tried to access names[5]. it returns undefined simply,gives no error.
After that I changed my array like this
var names=[];
for(var i=0;i<inputNumberByUser;i++) //guys my array is populating dynamically,depends upon user input
{
names.push({FirstName:'abc',LastName:'zyx'});
}
When I tried below code, it gives me error that, Could not read FirstName of undefined
names[5].FirstName;
why above line is giving error? it should just return undefined as normal array
names[5] and names[5].FirstName both are not defined. names[5] returns 'undefined' but names[5].FirstName error. thats my point. names[5].FirstName should also simply return 'undefined' as names[5] did
Why you are getting error?
Here names[5] returns undefined and you are trying to access FirstName property of undefined element. It's like trying to get address of someone who doesn't exists.
And You also have error in line for(var i=i<3;i++) may be you wanted to write for(var i=0; i<3; i++)
Possible Solution
If you are looking to push to names array then you should do something like below:
var names=[];
// Push objects to names
for (var i = 0; i < 3; i+=1) {
names[i] = {
firstName: 'Name: ' + i
}
// Lastname defined only for 2 index object
if (i === 2) {
names[i].lastName = 'Lastname only on 2';
}
}
for (var i = 0; i < 3; i+=1) {
// outputs names[i]
console.log(names[i]);
// Check whether lastName property exists on the element or not
if (!names[i].hasOwnProperty('lastName')) {
console.log('no lastName property defined');
}
}
Here we are creating object and assigning to names[i]. Remember, i is incrementing so each time we'll be assigning objects to new position.
Then in second loop, I am just referencing to those previously assigned values and checking whether they have lastName property defined on them or not.
If you are still confused let us know and we'll try to help you.
Because your for iteration does not reach the sixth (counting zero) index, but only the third.
What you are doing inside the for (var i = 0; i < 3; i++) is essentially:
names.push({FirstName:'abc',LastName:'zyx'});
names.push({FirstName:'abc',LastName:'zyx'});
names.push({FirstName:'abc',LastName:'zyx'});
The result of the iteration would be this:
console.log(names[0].FirstName); // "abc"
console.log(names[1].FirstName); // "abc"
console.log(names[2].FirstName); // "abc"
console.log(names[3].FirstName); // undefined
console.log(names[4].FirstName); // undefined
console.log(names[5].FirstName); // undefined
By doing console.log(names[5]) you are outputting the fifth index's content of the names variable. undefined in javascript is not necessarily an error message.
names[5]
^^^ undefined
By doing console.log(names[5].FirstName) instead, you are trying to access a property of an object that does not exist, since names[5] is undefined.
names[5].FirstName
^^^ undefined
Your array has three elements. Your trying to access the sixth element which in your above code will not exist.
For the first part of your question, you have created an array having 3 elements i.e var names=['a','b','c']; and you are trying to access 6th element from your defined array names[5], which not really exist. Hence it's returning undefined.
For the second part of your question you have following codes:
var names=[];
for(var i=0;i<3;i++)
{
names.push({FirstName:'abc',LastName:'zyx'});
}
So above piece of codes create names array having 3 element and each one is an object. So you have to access it like names[0].FirstName. But you are trying to access names[5].FirstName, where 6th elements in names array is not really exist.
Hope this will help you!

JavaScript: How to create new object properties/members and assign values inside a For Loop?

I am trying create a function to create and assign value to an object property/member. But I'm getting the error:
Uncaught TypeError: Cannot read property 'id' of undefined
The function is suppose to create a property/member called 'id', and it is also suppose to assign a value to the newly created property/member.
var add_Ids = function(array,index) {
for(var iii = 1; iii <= 3; iii++) {
array[index+iii].id = (array[index].id * 4)+iii;
}
array[index].id *= 4;
};
array is the array that I pass into the function.
index is the position in the array to start on with the For Loop
P.S. The For Loop is not overwriting anything important.
The element that corresponds to "array[index+iii]" is empty.
array[index+iii].id = (array[index].id * 4)+iii;
In that, If array[index+iii] is undefined before, Then array[index+iii].id would give that error you've mentioned.
So before accessing id check whether the property exists.
if(!array[index+iii]) array[index+iii] = {}; // initializing if its not present.
array[index+iii].id = (array[index].id * 4)+iii;
There's a couple of things at play here.
An array element must exist before it can be manipulated. Consider this code -
var my = [];
my[0].id = 1; // TypeError: Cannot set property 'id' of undefined
This is because exactly as the error states, my[0] is undefined here. Since your array is passed into a function, do one of the following (depends upon the circumstances/requirements of this function):
Ensure that you only pass in arrays that will meet the criteria of your function. In this case, your function expects an array with 3 elements of indices [iii+index,iii+index+3].
Ensure that the count you pass in doesn't cause your operation to exceed the length of the passed in array.
Fail with a meaningful error message - test for undefined and if so, generate a meaningful error.
If this matches what you are doing, you can check for undefined and make a default option if needed.
Example of the last:
var add_ids = function(array, index) {
for (var i = 1, i <= 3; i++) {
if (!array[index + i]) {
array[index + i] = generateDefaultObject();
}
array[index + i].id = (array[index].id * 4) + i;
}
array[index].id *= 4
}
Second, it seems as though that you expect this to work. It is similar to JavaScript's implicit global declaration. For example:
my = 4; // my didn't exist before this line, but now does as a global
is (unfortunately) valid JavaScript. Arrays do not support this kind of declaration for elements - they need to exist before you work with them.

Javascript how `length` is implemented

You know that in Javascript you can access the length of an text/array with length property:
var obj = ["Robert", "Smith", "John", "Mary", "Susan"];
// obj.length returns 5;
I want to know how this is implemented. Does Javascript calculates the length property when it is called? Or it is just a static property which is changed whenever the array is changed. My question is asked due to the following confusion in best-practices with javascript:
for(var i = 0; i < obj.length; i++)
{
}
My Problem: If it is a static property, then accessing the length property in each iteration is nothing to be concerned, but if it is calculated on each iteration, then it cost some memory.
I have read the following definition given by ECMAScript but it doesn't give any clue on how it is implemented. I'm afraid it might give a whole instance of array with the length property calculated in run-time, that if turns out to be true, then the above for() is dangerous to memory and instead the following should be used:
var count = obj.length;
for(var i = 0; i < count; i++)
{
}
Array in JavaScript is not a real Array type but it's an real Object type.
[].length is not being recalculated every time, it is being operated by ++ or -- operators.
See below example which is behaving same like array.length property.
var ArrayLike = {
length: 0,
push: function(val){
this[this.length] = val;
this.length++;
},
pop: function(){
delete this[this.length-1];
this.length--;
},
display: function(){
for(var i = 0; i < this.length; i++){
console.log(this[i]);
}
}
}
// output
ArrayLike.length // length == 0
ArrayLike.push('value1') // length == 1
ArrayLike.push('value2') // length == 2
ArrayLike.push('value3') // length == 3
ArrayLike.pop() // length == 2
ArrayLike.length === 2 // true
var a = ["abc","def"];
a["pqr"] = "hello";
What is a.length?
2
Why?
a.length is updated only when the index of the array is a numeric value. When you write
var a = ["abc","def"];
It is internally stored as:
a["0"] = "abc"
a["1"] = "def"
Note that the indexes are really keys which are strings.
Few more examples:
1.)
var a = ["abc","def"];
a["1001"] = "hello";
What is a.length?
1002
2.) Okay, let's try again:
var a = ["abc","def"];
a[1001] = "hello";
What is a.length?
1002
Note here, internally array is stored as
a["0"] = "abc"
a["1"] = "def"
a["1001"] = "hello"
3.) Okay, last one:
var a = ["abc"];
a["0"] = "hello";
What is a[0]?
"hello"
What is a.length?
1
It's good to know what a.length actually means: Well now you know: a.length is one more than the last numerical key present in the array.
I want to know how this is implemented. Does Javascript calculates the length property when it is called? Or it is just a static property which is changed whenever the array is changed.
Actually, your question cannot be answered in general because all the ECMA specs say is this:
The length property of this Array object is a data property whose
value is always numerically greater than the name of every deletable
property whose name is an array index.
In other words, the specs define the invariant condition of the length property, but not it's implementation. This means that different JavaScript engines could, in principle, implement different behavior.

use object name in javascript loop of array

I want to loop through an array of objects, check if the name of the object variable is equal to the id of an element passed to the function, and if so set the innerHTML of another object to the name property of the matching object.
ex.
var samplearray = new Array();
var Guy1 = new Object();
Guy1.name = "Bill";
Guy1.health = 100;
samplearray.push(Guy1);
Guy2.name = "Dan";
Guy2.health = 125;
samplearray.push(Guy2);
//this is all done previously by a function on pageload
function afunction(id){
for (item in samplearray)
{
if (item == id.id){
document.getElementById("changeme").innerHTML=samplearray[item].name;
}
}}
"item" in the if doesn't seem to refer to the name of the variable. If i check it with a custom var_dump function, it tells me the value is "11" and not "Guy1". I have no idea why.
edit:
the fixed for loop:
for (var item in samplearray)
{
if (samplearray[item].varname == id.id){
document.getElementById("changeme").innerHTML=samplearray[item].name';
}}
I don't quite understand what you're doing, but here's some comments on your code:
> var samplearray = new Array();
> var Guy1 = new Object();
> Guy1.name = "Bill";
> Guy1.health = 100;
> samplearray.push(Guy1);
> Guy2.name = "Dan";
> Guy2.health = 125;
> samplearray.push(Guy2);
It is considered better style (and a bit tidier) to use object and array initialisers*:
var guy1 = {name: "Bill", health: 100};
var guy2 = {name: "Dan", health: 125};
var samplearray = [guy1, guy2]
Also, variable names starting with a capital letter are, by convention, reserved for constructor functions.
> //this is all done previously by a function on pageload
You need to wait for elements to be available before interacting with them, waiting for the load event is one way of doing that.
> function afunction(id) {
What is id? You seem to treat it like an object later.
Ah, so id is a reference to an element, and id.id should return the element id.
> for (item in samplearray) {
You should declare variables so they do not become globals, so:
for (var item in samplearray) {
It's generally not a good idea to use for..in with an array because the order that members are returned may be different to their index order. Also, it will return all enumerable properties, including those on the prototype chain so you should guard against that if it's not what you want. Much better to use a for loop so you can guarantee the order and avoid non–numeric enumerable properties:
var item;
for (var i=0, iLen=samplearray.length; i<iLen; i++) {
item = samplearray[i];
> if (item == id.id){
So item will be a reference to an Object member of samplearray and id.id is a string so this will always return false, none of the following code will run.
> document.getElementById("changeme").innerHTML=item.name;
In the for..in version, item is a string property name, but you are treating it like an object so this will throw an error and script execution will stop.
In the for loop version, it's a reference to one of the objects in samplearray so the above should "work".
> document.getElementById("changeme").innerHTML=samplearray[item].name;
This should have worked provided item was a numeric property name and not some other enumerable property.
> //neither does this
> } }}
* Intialiser is a general term for an expression that creates an object (such as an Object, Array, Regular Expression, etc.). Where the initialiser uses literal values it may be called a "literal".
var Guy1 = new Object();
In this statement, the Guy1 object has no reference to the string "Guy1". The object exists without the variable. Indeed, the next statement could say:
var friend = Guy1;
and the object Guy1 object would be unchanged.
Besides this, I think you are getting confused about how the for...in loop works. Try reading more here: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/for...in
If you really want your Guy1 object to have a property of "Guy1", you will need to assign it as such:
Guy1.varname = 'Guy1';
And then you can check if (item.varname == id.id) once your for...in loop works correctly.

"push" is not a function [on elements returned by getElementsByTagName]

I have a bit of Javascript where I'm POSTing my form with an XMLHttpRequest, which otherwise works fine, but when I try to add the SELECT values to the array of INPUT values, it seems Javascript has lost its mind (or I have).
This function just builds the "name1=value1&name2=value2" string and passes it along.
The code:
function sendTheForm() {
var postData = '';
var inputArr = document.getElementsByTagName('input');
if (inputArr.hasOwnProperty(length)) alert("ARRAY!!");
var selects = document.getElementsByTagName('select');
var tmpObj = new Object();
for (var i = 0; i < selects.length; i++) {
tmpObj.name = selects[i].name;
tmpObj.value = selects[i].value;
inputArr.push(tmpObj);
}
for (var i = 0; i < inputArr.length; i++) {
if (inputArr[i].value) {
if (postData.length) postData += '&';
postData += inputArr[i].name;
postData += '=';
postData += escape(inputArr[i].value);
}
}
makeHttpReq(postData)
}
The error I get in FireFox is: "inputArr.push is not a function" It does say it's an Array.
Now, besides the fact that it's a method (not a function), it seems something is going badly wrong here, it's right under my nose and I can't see it. Help?
Earlier, I tried doing:
len = inputArr.length;
inputArr[len].name = ...
and also got an error that inputArr[31] was undefined. This is probably obvious, but I'm not seeing it. Help?
Having a .length property does not mean that it is an array. getElementsByTagName() returns a DOM 2 NodeList, not an Array.
As Phrogz already said, checking for a length property is NOT a way of checking for an array.
There's only one way to do that, so it works in ALL cases.
And that is using Object.prototype.toString.call(object).slice(8, -1).
Which gives you the Class value.
Value Class Type
-------------------------------------
"foo" String string
new String("foo") String object
1.2 Number number
new Number(1.2) Number object
true Boolean boolean
new Boolean(true) Boolean object
new Date() Date object
new Error() Error object
[1,2,3] Array object
new Array(1, 2, 3) Array object
new Function("") Function function
/abc/g RegExp object (function in Nitro/V8)
new RegExp("meow") RegExp object (function in Nitro/V8)
{} Object object
new Object() Object object
The reason why this isn't working is because the inputArr variable is actually a node list, not a real array.
If you do want it to be an array, you'd loop through it and add all the nodes in it to a real array or you can do this:
var node_array = Array.prototype.slice.call(node_list);

Categories