Skip to content

Spring 2014: Week 2

lmccart edited this page Oct 21, 2014 · 2 revisions

##Errata

  • Please send technical questions to class mailing list, I will respond there so everyone can benefit from the answers. Feel free to answer each others’ questions, too.
  • Lauren's section, date change for week 6: Friday, May 2 9:30-12
  • CDN: http://cdnjs.com/libraries/p5.js/

##OOP

###Intro to prototype based programming

  • We looked at simple objects already:
var obj = {}; 
  • In some languages, you create a class of objects to define a template for creating individual object instances. However, JS does not have actual classes, instead it uses prototype-based “pseudoclasses”. The distinction is technical, and a good thing to be aware of, but it works much like the classes you’re used to, and we’ll use the word class for simplicity.

  • Prototype-based programming is a style of object-oriented programming in which classes are not present, and behavior reuse (known as inheritance in class-based languages) is accomplished through a process of decorating existing objects which serve as prototypes. This model is also known as class-less, prototype-oriented, or instance-based programming.

  • Creating a class involves defining a constructor function and using the prototype object to add methods.

###Constructor

  • JavaScript has no “class” statement, instead it uses functions as classes. Defining a class is as simple as defining a function, this serves as the constructor. It is good practice to use a capital to distinguish a class definition.
function Car() {}
  • When you instantiate an object, a new object is created by calling the constructor, and the object is referred to within the class as this.

  • Dot operator -- we’ve seen this already. The dot operator is used to access properties or methods attached to one object. When called with this, it accesses the properties and methods of the newly instantiated object.

  • To set initial properties of an object, use this. within the constructor. Every instance of Car will have these properties when it is created.

function Car() {
   this.xpos = 0;
   this.ypos = 0;
   this.xspeed = 1;
   this.name = “Barbara”;
}
  • You can also pass in arguments to set initial properties of an object within the constructor.
function Car(name) {
   this.xpos = 0;
   this.ypos = 0;
   this.xspeed = 1;
   this.name = name;
}
  • About scope:
    • Scope of variable == region of program in which it’s defined.
    • Global variable has global scope (accessed anywhere).
    • Local variables exist within functions or classes, only defined within there.
    • Be careful about global vs local, may cause strange results.
    • Scope chain -- nested functions can access all variables of enclosing scopes up the chain

###Creating an instance

  • To create a new instance of an object obj we use the statement new obj, assigning the result (which is of type obj) to a variable to access it later.
var car0 = new Car(); // var car0 = { xpos: 0, ypos: 0, xspeed: 1, name: “Barbara” };
var car1 = new Car();

print(car0.name); // “Barbara”
print(car1.name); // “Barbara”
  • Any code within the constructor (class definition function) is executed at the time a new instance is created.

  • Just like normal JS objects, you can set or add properties to objects after they are created. These properties only affect the object you are updating, not any other instances.

car0.xpos = 10;
car0.wheels = 4;
print(car0.xpos); // 10
print(car1.xpos); // 0
print(car0.wheels); // 4
print(car1.wheels); // undefined

###Adding methods

  • To add functions to your class definition, use the prototype object. As mentioned last week, properties can be functions. In this case, you are creating a new property of the Car prototype called display, and setting it equal to a function you define.
Car.prototype.display = function() {
   rectMode(CENTER);
   stroke(0);
   fill(this.c);
   rect(this.xpos, this.ypos, 100, 50);
};
  • You can also update and set properties of the object from within the function.
Car.prototype.move = function() {
   this.xpos += this.xspeed;
   print(this.xpos);
};
  • Methods can also take arguments.
Car.prototype.setXSpeed = function(newSpeed) {
   this.xspeed = newSpeed;
   print(this.xspeed);
};
  • Methods can also take optional arguments.
Car.prototype.move = function(speed) {
   if (typeof speed !== ‘undefined’) {
      this.xpos += speed;
   } else {
      this.xpos += this.xspeed;
   }
};

###Calling methods and accessing properties

  • To call the methods of an object, you use the dot operator again. Methods, just like functions, are followed by parentheses and any arguments passed in.
car0.display();
car0.move();
car0.setXSpeed(10);

###Other helpers and tips

  • instanceof or .constructor
mySuperBall instanceof Ball // true
mySuperBall instanceof SuperBall // true

mySuperBall.constructor == Ball // false
mySuperBall.constructor == SuperBall // true
  • hasOwnProperty -- determines if object has specified property
print(mySuperBall.hasOwnProperty('xpos'));
  • in -- similar, determines if property found in object
print(‘gray' in mySuperBall);
var d = new Date();
print(d.getTime());

var text = "hello world"; // built-in shorthand for var text = new String("hello world");
print(text.length);
print(text.replace("world", "moon");

###Inheritance

  • Way to create a class as a specialized version of another class.

  • The specialized class is commonly called the child, and the other class is commonly called the parent.

  • You do this by assigning an instance of the parent class to the child class, and then specializing it.

  • See week2/inheritance example.

  • Call parent constructor.

function SuperBall(x, y, gray) {
   Ball.call(this, x, y, gray); // pass this, and any arguments for Ball constructor in order
}
  • Specify inheritance. This line tells the SuperBall to use the Ball object as it's template, and inherit all properties and methods from it's template.
SuperBall.prototype = new Ball();
  • Reset constructor. Now that you have told SuperBall to use Ball as the template, you have to tell it NOT to use the Ball constructor, to use it's own instead.
SuperBall.prototype.constructor = SuperBall;
  • Add or overwrite methods or properties.
Superball.prototype.move = function() {
   this.xpos -= this.xspeed;
};

Superball.prototype.change = function() {
   this.gray = sin(frameCount * 0.1)*125 + 125;
};

##Homework