JavaScript Introducing ES2015 Classes Static Methods

Static Methods video seems misleading for beginning learners

This video illustrates a static method in an ES6 class, but it seems confused about the purpose of static methods and this might leave beginners confused and ill-advised.

Essentially, a static method is shoehorned into acting like an instance method using the traditional Function.prototype.call mechanism (which seems like a more advanced technique than the rest of this course uses). At least while performing a bad practice like this, mention that good design would make changeColor an instance method.

But even better, why not show an example or two of how you might really use static methods (e.g. utility functions) and how the "this" keyword inside static methods binds to the class object (Bird) rather than a class instance.

Chris Collier
Chris Collier
17,774 Points

I couldn't agree more. If I didn't have prior experience with static methods in other languages, I would be totally lost as to why static methods exist.

1 Answer

izzy goldman
izzy goldman
12,542 Points
var Person = function (name, age){
    //private properties
    var priv = {};

    //Public properties
    this.name = name;
    this.age = age;

    //Public methods
    this.sayHi = function(){
        alert('hello');
    }
}

// A static method; this method only 
// exists on the class and doesn't exist 
// on child objects
Person.sayName = function() {
    alert("I am a Person object ;)");  
};

// An instance method; 
// All Person objects will have this method
Person.prototype.setName = function(nameIn) {
    this.name = nameIn;  
}

// Tests
var per = new Person('John Doe', 22);

//Shows alert
Person.sayName();

//TypeError: Object [object Object] has no method 'sayName'
per.sayName()

//Show alert
per.sayHi();

//John Doe
per.name;

//22
per.age;

per.setName('Jane Doe');

//Jane Doe
per.name;

An interesting example of the pre-ES6 techniques for implementing class-like behavior.

A good exercise would be to modernize and clean up this code: convert alert to console.log, convert Person to ES6 class, do something useful with the static method, get rid of unused code, etc

NOTE: the this.sayHi method defined in the Person constructor function creates a distinct function object for each Person object that is instantiated, unlike the setName instance method defined on Person.prototype which is shared among all the instances.

Normally we'd prefer this.sayHi to be a regular instance method defined on Person.prototype.

FILE: test1.html

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <title>Izzy Example</title>
  </head>
  <body>
      <p>See the Console in the Developer Tools to read the console.log output</p>
      <script src="test1.js"></script>
  </body>
</html>

FILE: test1.js

var Person = function (name, age){
    //Public properties
    this.name = name;
    this.age = age;
    this.sayHi = function() {
        console.log(`[Person].sayHi: name=${this.name}, age=${this.age}`);
    };
    console.log(`[Person] constructor: name=${this.name}, age=${this.age}`);
}

Person.prototype.setName = function(nameIn) {
    console.log(`[Person].setName: changed this.name from=${this.name}, to=${nameIn}`);
    this.name = nameIn;
};

// Tests
var p1 = new Person('John Doe', 22);
p1.sayHi();

let p2 = new Person('Janet Doe', 42);
p2.sayHi();

console.log(`p1.sayHi === p2.sayHi: ${p1.sayHi === p2.sayHi}`);

p1.setName('Jim Doe');
p1.sayHi();

p2.setName("Julie Doe");
p2.sayHi();

console.log(`p1.setName === p2.setName: ${p1.setName === p2.setName}`);

TRANSCRIPT: (FIrefox Developer Edition, 55)

[Person] constructor: name=John Doe, age=22
[Person].sayHi: name=John Doe, age=22
[Person] constructor: name=Janet Doe, age=42
[Person].sayHi: name=Janet Doe, age=42
p1.sayHi === p2.sayHi: false
[Person].setName: changed this.name from=John Doe, to=Jim Doe
[Person].sayHi: name=Jim Doe, age=22
[Person].setName: changed this.name from=Janet Doe, to=Julie Doe
[Person].sayHi: name=Julie Doe, age=42
p1.setName === p2.setName: true