If you're seeing this message, it means we're having trouble loading external resources on our website.

If you're behind a web filter, please make sure that the domains *.kastatic.org and *.kasandbox.org are unblocked.

Main content

Static functions vs. instance methods

Before we get to Algorithm #3 (accelerate towards the mouse), we need to cover one more rather important aspect of working with vectors and the PVector object: the difference between using static functions and instance methods.
Forgetting about vectors for a moment, take a look at the following code:
var x = 0;
var y = 5;
x = x + y;
Pretty simple, right? x has the value of 0, we add y to it, and now x is equal to 5. We could write the corresponding code pretty easily based on what we’ve learned about PVector.
var v = new PVector(0,0);
var u = new PVector(4,5);
v.add(u);
The vector v has the value of (0,0), we add u to it, and now v is equal to (4,5). Easy, right?
Let’s take a look at another example of some simple math:
var x = 0;
var y = 5;
var z = x + y;
x has the value of 0, we add y to it, and store the result in a new variable z. The value of x does not change in this example, and neither does y! This may seem like a trivial point, and one that is quite intuitive when it comes to mathematical operations with numbers. However, it’s not so obvious with mathematical operations in PVector. Let’s try to write the code based on what we know so far.
var v = new PVector(0,0);
var u = new PVector(4,5);
var w = v.add(u); // Don’t be fooled; this is incorrect!!!
The above might seem like a good guess, but it’s just not the way the PVector object works. If we look at the definition of add()...
PVector.prototype.add = function(v) {
    this.x = this.x + v.x;
    this.y = this.y + v.y;
 };
...we see that this code does not accomplish our goal. First, it does not return a new PVector (there is no return statement) and second, it changes the value of the PVector upon which it is called. In order to add two PVector objects together and return the result as a new PVector, we must use the "static" add() function.
A "static" function is a function that is defined on an object, but it doesn't change properties of the object. So why even define it on the object? Typically, it has something to do with the object, so it is logical to attach it to it. It treats the object more like a namespace. For example, all the static functions on PVector perform some sort of manipulation on passed in PVector objects and always return back some value. We could define those functions globally as well, but this way, we avoid global functions and have better ways of grouping related functionality.
Let's contrast. Here's how we use the add() instance method:
v.add(u);
That line of code would modify v, so we wouldn't need to save a return value. Conversely, here's how we use the add() static function:
var w = PVector.add(v, u);
If we didn't save the result of that function into a variable, that line of code would be useless, because the static version doesn't change the objects themselves. PVector's static functions allow us to perform generic mathematical operations on PVector objects without having to adjust the value of one of the input PVectors.
Here's how we would write the static version of add():
PVector.add = function(v1, v2) {
  var v3 = new PVector(v1.x + v2.x, v1.y + v2.y);
  return v3;
};
There are several differences here:
  • We define the function directly on the object, not on its prototype
  • We never access the this keyword inside the function
  • We return a value from the function
The PVector object has static versions of add(), sub(), mult(), and div(). It also has additional static functions that don't exist as instance methods, like angleBetween(), dot(), and cross(). We'll find ourselves using these functions as we continue making programs with PVector.

This "Natural Simulations" course is a derivative of "The Nature of Code" by Daniel Shiffman, used under a Creative Commons Attribution-NonCommercial 3.0 Unported License.

Want to join the conversation?

  • winston default style avatar for user Nicholas J.
    I think I understand, but I'm not completely sure. Please correct my summary if something seems off.

    Instance methods alter their object variable while static functions return the value after manipulation without altering. Is that the only major difference between the two types aside from implementation details?

    The other question is about calling directly on the object not the prototype. This means I have to use the actual object name, in this case PVector.add(v, u), and not an instance of the object like velocity.add or vector1.add.
    (34 votes)
    Default Khan Academy avatar avatar for user
    • starky ultimate style avatar for user jdsutton
      Instance methods don't necessarily alter variables. It's simply a function that gets "shipped out", so to speak, with each instance of that object you create. They are relative to the individual object, hence the keyword this.

      A static method belongs to the class itself. You can call it without instantiating any members of that class. That's why the method is called from the class name and not from a specific instance.
      (29 votes)
  • hopper jumping style avatar for user abhishek994sharma
    var v = new PVector(1,5);
    var u = PVector.mult( v , 2);
    var w = PVector.sub( v , u);
    w.div(3);

    why only in first line "new" is used before <i>Pvector</i>??
    (11 votes)
    Default Khan Academy avatar avatar for user
    • piceratops ultimate style avatar for user Dan Fletcher
      The line
      var v = new PVector(1,5);
      is creating a new PVector object

      The lines
       var u = PVector.mult(v, 2);
      var w = PVector.sub(v, u);

      are using the static functions included with PVector
      and then storing the result which is a "new PVector" inside of a variable.

      remember that when we use
      v.mult(u)

      we are changing the value of v. There is no value that is actually returned so it can't be stored inside of another variable.

      on the other hand
       var u = PVector.mult(v, 2);

      is a function, that takes two parameters, and returns a PVector object, storing it inside of "u"

      The new is used inside of the function itself.
      (13 votes)
  • mr pink red style avatar for user Bob Everton
    I can't seem to get the first step in the static challenge. Here's my code. Any help.

    var v = new PVector(1,5);
    var w = 2;
    PVector.mult = function(u,w) {
    var u = new PVector(v.x.mult.w,v.y.mult.w);
    return u; };
    (6 votes)
    Default Khan Academy avatar avatar for user
  • hopper jumping style avatar for user Aaron Nelson
    So, the way I was thinking is that there is no use for a static function that does not return a value. Then I thought about passing things by reference as opposed to by value. Can you do this sort of thing in JavaScript?
    (5 votes)
    Default Khan Academy avatar avatar for user
    • starky ultimate style avatar for user jdsutton
      Yes. Objects are passed as references. When you pass in an object to a function, you are handing it a reference to that object and not a copy of it. In the example above, return v3; is returning a reference to an object.
      (4 votes)
  • aqualine ultimate style avatar for user Curiosity
    I am having some trouble figuring out the Static function challenge.
    Could I see someone's spin off, to see what I did wrong?
    (1 vote)
    Default Khan Academy avatar avatar for user
    • purple pi purple style avatar for user scottiegazelle
      I have been having trouble with this one, but it seems to be related to the brower. I've found that reloading the entire page seems to make things I'm fairly certain of actually pass, though I'm stymied at the end and can't tell if it's an error or a code problem.

      For the first step, however, I used:

      var u = PVector.mult(v, 2);
      (11 votes)
  • piceratops ultimate style avatar for user RowanH
    In the Mouse stalker challenge, I have worked out I need to use this code:
    var maxDir = new PVector(width - 1, height - 1);//maximum vector to mouse
    var maxMag = maxDir.mag();

    But why this allowed? maxDir.mag() looks like an instance method to me. Why does it return a value? I was expecting to use something like var maxMag = PVector.mag(maxDir);
    (5 votes)
    Default Khan Academy avatar avatar for user
    • old spice man green style avatar for user Bob Lyon
      It's hard for others to explain your misunderstandings...

      mag is one of many methods associated with PVector instances. It returns the magnitude (or length) of the PVector instance. Lengths are simple numbers, not vectors.

      Oddly enough, PVector does supply a mag static function. It's mechanically generated in the same manner as get, add, sub, etc. It is pretty useless in that it always returns a clone of its first argument, the same as invoking PVector.get
      (3 votes)
  • leaf blue style avatar for user costas
    I m trying to understand the implication of" 'We define the function directly on the object, not on its prototype'. Then, a second related question is why instances of PVector don't inherit these static methods too.

    There seem to be (at least) 3 ways of adding methods to an object (call it Vector):
    1. var Vector = function(x, y) {
    this. x = x,
    this.y = y,
    this.add = function(a, b) ......};};
    2. Vector.add = function(a, b) .....
    3. Vector.prototype.add = function(a, b) .....

    Do they do the same thing? I guess though only the first way (1.) makes the method automatically inheritable in any object based on Vector. For way 3, you have to call Vector's prototype into the new object's prototype. What does 2. do ? I thought it might be equivalent to 1. which would make it automatically inheritable, or not?
    (5 votes)
    Default Khan Academy avatar avatar for user
    • old spice man green style avatar for user Bob Lyon
      Way 1 and way 3 are similar, but way 2 has nothing to do with this object. Way 2 is deployed as a way to keep from "polluting the global namespace". One could have written var VectorAdd(a, b) {... and been done, but by hanging another property (a static function) onto Vector one avoids another var and signals that the function is intimately associated with the Vector function.

      The non-static functions that reference this object are "methods". If all their functionality is derived from this, then the two ways are functionally equivalent. However, the storage requirements differ. By placing the method in the prototype (way 3) one guarantees that a single copy of the method is shared by all constructed objects. If one defines the method within the constructor function (way 1), then each object gets its own unique copy of that function. For example,

          var a = new Vector(3, 4);
      var b = new Vector(12, 5);
      prinltn(a.add === b.add);

      prints false with way 1 and true with way 3. So until you know and the uses of "closures", place your methods on the prototype property.
      (2 votes)
  • duskpin ultimate style avatar for user Farisch
    It was not really clear to me what the difference is between defining the function directly on the object or defining it on its its prototype. What happens on the background and why is this difference so important?
    (3 votes)
    Default Khan Academy avatar avatar for user
    • old spice man green style avatar for user Bob Lyon
      Defining another function on the object constructor is no big deal. For example. we could have had something like
      /*
      * Return a new PVector that is the
      * summation of PVectors a and b.
      */
      var addPVectors = function(a, b) {
      ...
      };
      But instead we use PVector.add is do exactly the same thing. The latter does not pollute the global name space with a bunch more names. It also makes it clear the function is naturally provided by the one, same library that creates & handles PVectors. Furthermore the names of the static functions are easily guessed given the names of the objects' methods.

      No big deal. Just good software engineering.
      (3 votes)
  • hopper cool style avatar for user Kentst. H
    Why do we have to write add instead of _+=_ or _ = _+__ on vectors?
    (2 votes)
    Default Khan Academy avatar avatar for user
    • orange juice squid orange style avatar for user Troy Cook
      The + operator can only add two single numeric values or used to place two strings together. The vector could have one, two or three values. The + sign cannot add several pairs of numbers and special methods are provided that will perform those tasks. The vector object has different methods that are far more complex than just basic addition and subtraction.

      Methods
      get() Gets the x, y, z component of the vector
      set() Sets the x, y, z component of the vector
      mag() Calculates the magnitude (length) of the vector and returns the result as a float
      add() Adds one vector to another
      sub() Subtracts one vector from another
      mult() Multiplies the vector by a scalar
      div() Divides the vector by a scalar
      dist() Calculate the Euclidean distance between two points
      dot() Calculates the dot product
      cross() Calculates the cross product
      normalize() Normalizes the vector
      limit() Limits the magnitude of the vector
      angleBetween() Calculates the angle between two vectors
      array() Return a representation of the vector as an array

      Copied from:
      http://processingjs.org/reference/PVector/
      (4 votes)
  • aqualine seed style avatar for user Martin Nicol
    I go over and over this but still get lost. I know OOP constructor, prototypes and calling a new child. I know you can just add a number or a var letter to say, this.x as in this.x + w/2;
    When this talks about, this does not return a new PVector, and the static function is defined on a object, treat object like namespace, passed in PVector objects, save a return value, directly on the object, not on its prototype. I understand individual words from other context but I cannot apply it to this topic. If there was a teacher she would be pointing to these things in the code but when we just have words and they all build on each other, so I get lost. I have passed the challenges up to static function but I don't understand them. It's just language but where is the interpretation/translation?
    (3 votes)
    Default Khan Academy avatar avatar for user