Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Javascript classes and variable references

Tags:

javascript

I'm trying to solve this puzzle minded Javascript OOP problem.

So I have the following class :

var ClassA = function() {
    this.initialize();
}

ClassA.prototype = {

    methods : ['alpha','beta','gama'],

    initialize : function() {
        for ( var i in this.methods ) {
            this[this.methods[i]] = function() {
                console.log(this.methods[i]);
            }
        }
    }
}

var a = new ClassA();

When I call every method I expect to print the name of it, right? But here is what i get :

a.alpha(); // returns gama ?!?
a.beta();  // returns gama ?!?
a.gama();  // returns gama

But when my class looks like this :

var ClassB = function() {
    this.initialize();
}

ClassB.prototype = {

    methods : ['alpha', 'beta', 'gama'],

    initialize: function() {
        for ( var i in this.methods ) {
            this.addMethod(this.methods[i]);
        }
    },

    addMethod: function(method) {
        this[method] = function() {
            console.log(method);
        }
    }

}

var b = new ClassB();

b.alpha(); // returns alpha
b.beta();  // returns beta
b.gama();  // returns gama

Why is this happening ?

like image 555
drinchev Avatar asked Apr 02 '12 21:04

drinchev


People also ask

Can JavaScript classes have variables?

To declare a variable within a class, it needs to be a property of the class or, as you did so, scoped within a method in the class. It's all about scoping and variables are not supported in the scope definition of a class.

How do you declare a class variable in JavaScript?

One way to define a class is using a class declaration. To declare a class, you use the class keyword with the name of the class ("Rectangle" here).

What are JavaScript classes?

A JavaScript class is a blueprint for creating objects. A class encapsulates data and functions that manipulate data. Unlike other programming languages such as Java and C#, JavaScript classes are syntactic sugar over the prototypal inheritance. In other words, ES6 classes are just special functions.

What are JavaScript references?

In JavaScript, unlike in most other popular programming languages, the references are pointers to values stored in variables and NOT pointers to other variables, or references.


1 Answers

for ( var i in this.methods ) {
      this[this.methods[i]] = function() {
          console.log(this.methods[i]);
       }
}

Your problem lies here. When this loop ends, i is the last element. Each function uses the same i, so they are all the last element.

When you use addMethod you are making a closure to "capture" the correct value.

EDIT: When you call addMethod you are "copying" the value, instead of using the i value, which changes with each loop iteration.

like image 128
Rocket Hazmat Avatar answered Nov 08 '22 18:11

Rocket Hazmat