Javascript - 为什么没有递归?

gop*_*rao 2 javascript recursion constructor

递归没有发生?任何人都可以指出为什么?

function a() {
console.log("xx");
console.log(this);
a();
}
var a2 = new a();
Run Code Online (Sandbox Code Playgroud)

T.J*_*der 6

回答更新的问题:

您对问题的更新完全改变了它.新代码确实将永远递归:

var counter = 0;
function a() {
  snippet.log(counter);
  if (++counter < 10) {  // To avoid recursing forever
    a();
  }
}
var a2 = new a();
Run Code Online (Sandbox Code Playgroud)
<!-- 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>
Run Code Online (Sandbox Code Playgroud)


回答原始问题:

递归没有发生?任何人都可以指出为什么?

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

一个递归调用,但递归调用只在一次递归调用后停止,因为这一行:

Object.getPrototypeOf(this).constructor();
Run Code Online (Sandbox Code Playgroud)

...调用athis设置为全局对象(因为你使用松散模式*),未设定为实例.所以在下一次通话,Object.getPrototypeOf(this)回复Object.prototype和通话时Object().

如果你把它改成了

Object.getPrototypeOf(this).constructor.call(this);
Run Code Online (Sandbox Code Playgroud)

然后它将永远递归(所以我添加了一个计数器,所以它没有这样做),因为我们调用constructor并设置this为与当前相同this,所以下一个调用将a再次使用,并再次, 然后再次...

var counter = 0;
function a() {
  snippet.log(counter);
  if (++counter < 10) {
    Object.getPrototypeOf(this).constructor.call(this);
  }
}
var a2 = new a();
Run Code Online (Sandbox Code Playgroud)
<!-- 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>
Run Code Online (Sandbox Code Playgroud)


*"因为你正在使用松散模式" - 我知道这一点,因为如果你使用严格模式,那this将是undefined,并且Object.getPrototypeOf(undefined)会抛出错误.


边注:

我不认为这是你问题的重点(根本),但是:你不能真正依赖于constructor野外的财产.虽然JavaScript规范定义为正常函数创建并分配给它们的prototype属性的对象将具有constructor指向函数的属性,这是规范所说的总和constructor.在说明书中没有使用该财产的任何东西.我之所以提到这一点,是因为人们通过这样做打破这种联系是很常见的:

function Foo() {
}
Foo.prototype = {
    something: function() {
        // ...
    }
};
Run Code Online (Sandbox Code Playgroud)

在这一点上,Foo.prototypeconstructor属性是指Object,不Foo.

如果您只使用自己的代码,并且没有破坏constructor,那么你很好.可悲的是,通常会看到它以这种方式被打破.