Gerard
Gerard

Reputation: 87

variable visibility in javascript

I am struggling to understand how variables are referenced and stay alive in Javascript. In the following I have two types of object, a Note and an IntervalBuilder which takes a Note and creates a second Note.

function Note() {
        this.key = 1 + Math.floor( Math.random() * 13); // from 1 to 13 inclusive
        this.setKey = function setKey(i) { key = i; };
        this.getKey = function getKey() { return this.key; } ;  // {return key} is a ReferenceError!!
}

function IntervalBuilder() {

    this.setPerfectFifth = function setPerfectFifth(root) {
    this.fifth = new Note();
    console.log("this.fifth: " + this.fifth);
    this.y = root.key;
    console.log("root.key: " + root.key );
    console.log("y: " + this.y );
    this.fifth.setKey( this.y + 4 );
    return this.fifth;
    };
}

With the above I can now do this:

var x = new Note();
var ib = new IntervalBuilder();
ib.setPerfectFifth(x);

However, the instance ib now has a member named fifth! What I was hoping for was that I could assign the return value (a Note) from setPerfectFifth to a variable and let fifth vanish. How is that done?

Many thanks for any help, I find lots of this very confusing.

Gerard

Upvotes: 0

Views: 68

Answers (2)

Badacadabra
Badacadabra

Reputation: 8517

I do not know exactly what you want to achieve, but I think you want the following code structure:

// ==============================
// NOTE "CLASS"
// ==============================

var Note = (function () {
  // Constructor
  function Note() {
    this._key = 1 + Math.floor( Math.random() * 13);
  }

  // Getter
  Note.prototype.getKey = function () {
    return this._key;
  };

  // Setter
  Note.prototype.setKey = function (i) {
    this._key = i;
  };

  return Note;
})();

// ==============================
// INTERVAL BUILDER "CLASS"
// ==============================   

var IntervalBuilder = (function () {

  // Constructor
  function IntervalBuilder() {}

  // Private members
  var fifth = null,
      y = 0;

  // Setter
  IntervalBuilder.prototype.setPerfectFifth = function (root) {
    fifth = new Note();   
    y = root.getKey();
    fifth.setKey(y + 4);
    return fifth;
  };

  return IntervalBuilder;
})();

// ==============================
// CLIENT CODE
// ==============================

var x = new Note(),
    ib = new IntervalBuilder();

ib.setPerfectFifth(x);

Upvotes: 1

SVSchmidt
SVSchmidt

Reputation: 6567

Since you titled your quesion variable visibility in javascript what is basically going on is: In this.fifth = new Note(); the keyword this references the instance (the ib of var ib = new ...). So you attach your newly created Note to the instance. In JavaScript, as long as a variable can be reached starting with the global Object (window, when you think of a graph), it won't get garbage-collected away.

What you want is: var fith = new Note(), which will create a local variable which will get freed as soon as the function execution ends. Clearly, every usage of this.fifth then has to be replaced by just fith.

Upvotes: 1

Related Questions