user1571609
user1571609

Reputation:

Javascript scope and variables

var name = "Bob";

var book = {
    name: "Harry Potter",
    writeName: function() {
        return function() {
            document.writeln(this.book.name);
        }
    }
};

When I call this

book.writeName()();

I want it to print Harry Potter (not Bob) which it does above, however this:

var book2 = book;
book = null;
book2.writeName()();

Now looks for this.book (which is null) where it should be looking for this.book2

How can I reference the variable?

Upvotes: 5

Views: 88

Answers (4)

Andy
Andy

Reputation: 63589

Because this changes when the context changes you need to save a reference to the original this. Here I've used _this

var book = {
  name: "Harry Potter",
  writeName: function() {
    var _this = this;
    return function() {
      console.log(_this.name);
    }
  }
};

book.writeName()() //  Harry Potter

var book2 = book;
book = null;
book2.writeName()();  //  Harry Potter

Demo

Upvotes: 1

Bergi
Bergi

Reputation: 665344

What you need here is a variable in the writeName closure:

var book = {
    name: "Harry Potter",
    writeName: function() {
        var name = this.name; // turn dynamic property into closure variable
        return function() {
            document.writeln(name);
        }
    }
};
book.writeName()(); // Harry Potter

Instead of storing only the name in the closure, you also could store a reference to the object like in @Quentin's answer. It might make a difference if you plan to change the .name property before calling the returned function.

For the question whether to use this or book for referencing your object see Javascript: Object Literal reference in own key's function instead of 'this'.

Upvotes: 5

Royi Namir
Royi Namir

Reputation: 148714

try this : http://jsbin.com/pagumiwi/4/edit

var name = "Bob";

var book = {
    name: "Harry Potter",
    writeName: function() {
        return function() {
            document.writeln(this.name);
        }
      }()
    };



book.writeName(); //would also work
var book2 = book;
book = null;
book2.writeName(); //would also work

Upvotes: 2

Quentin
Quentin

Reputation: 944295

Since you are returning a function, you are going to lose whatever context you got from calling the function that generates it.

You need that context to reference the object, so you need to preserve it.

writeName: function() {
    var myBook = this;

You then need to use that preserved context:

    return function() {
        document.writeln(myBook.name);
    }

Upvotes: 3

Related Questions