Jumping from Processing to p5.js... whaaa?

Hi, getting into Javascript (p5.js) from Processing to embed sketches on my website.

Right from the start there are two things I don’t get.
variables have no declared type?
arrays have no declared length?

Here is a piece of code which does not do what I’d thought it would do (filled squared vibrating with random greys); method for getting grey level is intentionally convoluted, it is only to test how arrays work:

let arr = [];

function setup() {
  createCanvas(100, 100);
  // fill the array with random values
  for (let i=0; i<100; i++) {
    arr[i] = int(random(255));
  }
  class_test = new myClass(arr);
  fill(255, 127, 0);
}

function draw() {
  for (let j=0; j<arr.length; j++) {
    // get grey level from array in class_test
    fill(class_test.arry[j]);
    rect(0,0,100,100);
  }
}

class myClass {
  constructor(a) {
    this.arry = a;
  }
}

I realize Processing has less to do with Javascript than the streamlined look of the editor might let me think, but being somewhat fluent in Processing appears to be simply misleading here, and I’d appreciate someone pointing out what’s wrong with this simple sketch so I can make one extra step into p5.js.

EDIT: I’ve read that classes don’t exist in JS, that you can only make constructor functions. But then on the other hand why would someone write something like this?

1 Like
  1. JavaScript is a dynamically typed programming language. So variables do not have a declared type and type checks are not performed. You can change what type of value is stored in a variable. You can access any property name on any type of value (i.e. foo.bar is never an error so long as foo is not null or undefined, if bar does not exist on the value stored in foo this simply returns undefined). However be careful calling methods that don’t exist because trying to invoke undefined like it’s a function will cause an error at runtime.
  2. JavaScript arrays are resizable, and can be sparsely populated. So you can take an empty array let foo = [] and set the 100th value foo[99] = 'bar' at which point foo.length will be 100 but all other values foo[0], foo[1], … will return undefined.
  3. Processing code is basically Java, and p5.js is a library for JavaScript. Despite the unfortunate and purely marketing motivated naming of “JavaScript” which is actually properly called “ECMA Script”, these two programming languages have very little to do with each other.
  4. JavaScript does have classes* and can be used as an Object Oriented programming language. The class declaration in your example is correct, and is the preferred modern style (there are other ways to declare classes, but they mainly show up because JavasScript didn’t always have this modern syntax).
  5. Your code seems to be working, but it has some idiosyncrasies, and perhaps it is not doing what you intended
// Why declare this as a global variable when it is going to be contained by your class instance?
let arr = [];

function setup() {
  createCanvas(100, 100);
  // fill the array with random values
  for (let i=0; i<100; i++) {
    arr[i] = int(random(255));
  }
  // This implicitly creates a global variable class_test. This is legal in javascript but it is
  // preferable to explicitly declare variables at the top of your file
  class_test = new myClass(arr);
  fill(255, 127, 0);
}

function draw() {
  // You're checking the global arr variable length and then using the myClass instance
  // property arry below. You should use the same thing in both places for consistency.
  for (let j=0; j<arr.length; j++) {
    // get grey level from array in class_test
    fill(class_test.arry[j]);
    // I'm not sure what you intended to do, but this is going to successively fill the entire
    // canvas with a single rectangle, so only the last rectangle will actually be visible.
    rect(0,0,100,100);
  }
}

class myClass {
  constructor(a) {
    this.arry = a;
  }
}

* If somebody says that “classes don’t exist in JS” they are just being pedantic. Because of it’s dynamic nature, JavaScript can actually store arbitrary properties on a function. So JavaScript leverages this capability in order to support object oriented programming. A class is basically a function that has a prototype object on it. And the new keyword creates a copy of YourFunction.prototype object, invokes YourFunction with that object accessible via the this keyword, and the returns that object. So technically yes, it’s all just functions all the way down, but thinking about these as Object Oriented Classes is perfectly valid and correct.

4 Likes

@KumuPaul Thanks a lot for your long answer, it does clear up a few things.

Dynamically typed… that opens up a whole new way of doing things. Needs works to wrap the head around.

Thanks for your comments in the code. I know it’s a very clumsy way just to do what it does. I wanted to construct an object with an array as parameter just to see if/how it worked, and to see if I could access values of the object using object.variable syntax. Now I understand why my rect() remains the same color on screen; it needs a call to draw() between each new-colored rect() to actually display the color change. So it’s just poorly written code, and not fundamental misunderstanding of JavaScript.