2

Recursion is not happening? Can anyone point out why?

function a() {
console.log("xx");
console.log(this);
a();
}
var a2 = new a();
1
  • 1
    Your edit completely changes the question, and if you tried it, you'd find that you would indeed get infinite recursion doing that. It's not appropriate to fundamentally change questions once they've been answered, I recommend using the "rollback" feature to return to the original text. Commented Apr 22, 2015 at 14:44

1 Answer 1

6

Answer to the updated question:

Your update to the question completely changes it. The new code will indeed recurse forever:

var counter = 0;
function a() {
  snippet.log(counter);
  if (++counter < 10) {  // To avoid recursing forever
    a();
  }
}
var a2 = new a();
<!-- Script provides the `snippet` object, see http://meta.stackexchange.com/a/242144/134069 -->
<script src="http://tjcrowder.github.io/simple-snippets-console/snippet.js"></script>


Answer to the original question:

Recursion is not happening? Can anyone point out why?

function a() {
console.log("xx");
console.log(this);
Object.getPrototypeOf(this).constructor(); //Isn't this a recursive call?
}
var a2 = new a();

It is a recursive call, but the recursion stops after just one recursive call because this line:

Object.getPrototypeOf(this).constructor();

...calls a with this set to the global object (because you're using loose mode*), not set to the instance. So on the next call, Object.getPrototypeOf(this) returns Object.prototype, and calls Object().

If you changed it to

Object.getPrototypeOf(this).constructor.call(this);

then it would recurse forever (so I've added a counter to the following so it doesn't do that), because we're calling constructor and setting this to be the same as the current this, so the next call will use a again, and again, and again...

var counter = 0;
function a() {
  snippet.log(counter);
  if (++counter < 10) {
    Object.getPrototypeOf(this).constructor.call(this);
  }
}
var a2 = new a();
<!-- Script provides the `snippet` object, see http://meta.stackexchange.com/a/242144/134069 -->
<script src="http://tjcrowder.github.io/simple-snippets-console/snippet.js"></script>


* "because you're using loose mode" - I know this because if you were using strict mode, this would be undefined, and Object.getPrototypeOf(undefined) would throw an error.


Side note:

I don't think it's the point of your question (at all), but: You can't really rely on the constructor property in the wild. While the JavaScript specification defines that the object created for normal functions and assigned to their prototype property will have a constructor property pointing back to the function, that's the sum total of what the specification says about constructor. Nothing in the specification uses that property for anything. I mention this because it's quite common for people to break that link, by doing this:

function Foo() {
}
Foo.prototype = {
    something: function() {
        // ...
    }
};

At that point, Foo.prototype's constructor property refers to Object, not Foo.

If you're only working with your own code, and you don't break constructor, you're fine. Sadly, though, it's common to see it being broken in this way.

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

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.