petabyte
petabyte

Reputation: 1567

Why does this object not get garbage collected?

function Car() {
    this.interval = {id: null};
    this.i = 0;
    this.start = function() {
        this.interval.id = setInterval(this.go.bind(this), 1000);
    }

    this.go = function() {
        this.i++;
        if (this.i >= 5) {
            console.log("kill");
            this.kill();
        } else {
            console.log("go");
        }
    };

    this.kill = function() {
        clearInterval(this.interval.id);
    };
}

var car = new Car();
car.start();
car = null;

When I run the above I get

go
go
go
go
kill

Shouldn't car object be garbage collected since it is unreachable? How is setInterval able to access the car object? And does the car object continue to exist afterwards?

Upvotes: 0

Views: 73

Answers (2)

jfriend00
jfriend00

Reputation: 707786

The car object you created is still reachable by the closure that setInterval() is within. That closure creates a reference to the car object so it can't be garbage collected until that closure is also unreachable.

The closure is created because this.go.bind(this) has a reference to this which is your car object. The JS interpreter knows that the car object is still reachable by the setInterval() callback function and thus there is still a live reference.

If the setInterval() were to stop itself after a certain number of iterations or any other condition, then the object would become eligible for garbage collection because that setInterval() reference would no longer be alive and there would be no other references still alive.

Upvotes: 1

Thilo
Thilo

Reputation: 262734

  this.go.bind(this)

This effectively creates a closure that wraps your car (this).

As long as that closure is alive, it will keep the car around.

And setInterval of course remembers the function it is supposed to run.

Upvotes: 1

Related Questions