0

Excuse the title I didn't know how to succinctly state what I'm trying to do. I'm trying to teach myself javascript from snippets from books as well as the internet. My first test script is trying to make an array of objects (stars), and use a for loop to read the data in those objects to draw circles to the canvas at points stored in the objects.

code:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1

/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
  <head>
    <script type="text/javascript">
      var star = {}
      function the_stars() {}
      the_stars.prototype = {
        constellation: "test",
        x: 120,
        y: 120
      };
      function the_stars.set(c,xx,yy) { alert("called"); constellation=c; x=xx; y=yy; };
      star["Polaris"] = new the_stars();
      star["Polaris"].set("Ursa Minor",250,20);
      alert(star["Polaris"].constellation);
      star["Mizar"] = new the_stars();
      star["Mizar"].set("Ursa Major",50,75);
      star["Alderbaran"] = new the_stars();
      star["Alderbaran"].set("Taurus",300,150);
      star["Rigel"] = new the_stars();
      star["Rigel"].set("Orion",350,370);
      function make()
      {
         alert("in make");
         var context = document.getElementById('c').getContext('2d');
         context.fillStyle = 'white';
         context.strokeStyle = 'white';
         for(var thestar in star)
         {
            alert("in for loop "+thestar+thestar.x+thestar.y);
            context.arc(thestar.x,thestar.y,40,0,2*Math.PI);
            context.stroke();
         }
      }
    </script>
    <style type="text/css">
       #c {
           background-color:#000000;
           width:450px;
           height:450px;
       }
    </style>
  </head>
  <body onLoad='make()'>
    <h1>stars</h1>
    <canvas id='c'>
    </canvas>
  </body>
</html>

The alert in the for loop gives me the correct name of the star, but tells me x and y are undefined. But how can this be when alert(star["Polaris"].constellation); prints "test", so function set doesn't work but the default values were set but alert("in for loop "+thestar+thestar.x+thestar.y); prints "undefinedundefined. How is this possible?

Dhanu Gurung
  • 8,480
  • 10
  • 47
  • 60
jason dancks
  • 1,152
  • 3
  • 9
  • 29
  • `function the_stars.set` What is that? – Qantas 94 Heavy Jan 06 '14 at 05:19
  • 1
    Because the way you are setting variable start[] is not an array. It's an object. Arrays can only be accessed via numerical indexes. You for loop in this case will run for longer than the number of indexes you have set. Check the link http://stackoverflow.com/questions/9526860/why-does-a-string-index-in-a-javascript-array-not-increase-the-length-size for more details. – jsjunkie Jan 06 '14 at 05:28

3 Answers3

4

You have 2 errors. Instead of doing:

function the_stars.set(c,xx,yy) { 
   alert("called"); 
   constellation=c; x=xx; y=yy; 
};

You should do:

the_stars.prototype.set = function(c,xx,yy) { 
    alert("called"); 
    this.constellation=c; this.x=xx; this.y=yy; 
};

This is the way for defining member methods in js.

Then, in your for loop, instead of this:

for(var thestar in star)
     {
        alert("in for loop "+thestar+thestar.x+thestar.y);
        ...
     }

You should have this:

 for(var key in star)  //Note the key here
     {
        var thestar = star[key];  //This way you get the item
        alert("in for loop "+thestar+thestar.x+thestar.y);
        ...
     }

This is because the for...in loop gets the key and not the actual element as foreach does in other languages.

Here you have it working: http://jsfiddle.net/edgarinvillegas/CwVGv/

Cheers, from La Paz, Bolivia

Edgar Villegas Alvarado
  • 18,204
  • 2
  • 42
  • 61
  • Thanks for your help. Why do the circles look pixelated, as if it was expanded in size? And why are there lines being drawn? – jason dancks Jan 07 '14 at 03:54
1

Actually problem is exists how you are access in for loop. thestar is just a key not a object at all. So It is gave error. You need to access it by star[thestart]. Like that

     for(var thestar in star)
     {
        alert("in for loop "+thestar+star[thestar].x+star[thestar].y);
        context.arc(star[thestar].x,star[thestar].y,40,0,2*Math.PI);
        context.stroke();
     }
kuldeep.kamboj
  • 2,566
  • 3
  • 26
  • 63
1

See the working version here:

<script type="text/javascript">
  var star = {}
  function the_stars() {}
  the_stars.prototype = {
    constellation: "test",
    x: 120,
    y: 120,
    set: function(c,xx,yy){
      alert("called"); this.constellation=c; this.x=xx; this.y=yy; 
    }
  };

  star["Polaris"] = new the_stars();
  star["Polaris"].set("Ursa Minor",250,20);
  alert(star["Polaris"].constellation);
  star["Mizar"] = new the_stars();
  star["Mizar"].set("Ursa Major",50,75);
  star["Alderbaran"] = new the_stars();
  star["Alderbaran"].set("Taurus",300,150);
  star["Rigel"] = new the_stars();
  star["Rigel"].set("Orion",350,370);

  console.log(star);
  function make()
  {
     alert("in make");
     var context = document.getElementById('c').getContext('2d');
     context.fillStyle = 'white';
     context.strokeStyle = 'white';
     for(var thestar in star)
     {
        alert("in for loop "+thestar+star[thestar].x+star[thestar].y);
        //console.log(star[thestar]);
        //console.log("in for loop "+thestar+star.x+star.y);

        context.arc(star[thestar].x,star[thestar].y,40,0,2*Math.PI);
        context.stroke();
     }
  }
</script>
Reza Mamun
  • 5,991
  • 1
  • 43
  • 42