0

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

2
  • 2
    If you set this.fifth in IntervalBuilder, it is a public attribute on any instance. Try changing this.fifth = new Note() to var fifth = new Note();. This sill make it so that it isn't attached to the instance, and is private for the method. Then, change every occurrence of this.fifth in your function to just fifth, as it is now a private variable in the scope of that function. Is this what you're looking for? Commented Apr 29, 2017 at 17:05
  • if setPerfectFifth doesn't set any property on ib, what does it set ? Commented Apr 29, 2017 at 17:06

2 Answers 2

1

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.

Sign up to request clarification or add additional context in comments.

Comments

1

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);

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.