Javascript局部变量生存期

时间:2018-07-05 17:36:46

标签: javascript three.js var

我在C,C ++方面很先进,但是对Javascript还是陌生的。我正在学习three.js,但无法理解这里发生的事情:

var camera, scene, renderer, control;

init();

function init() {
    scene = new THREE.Scene();

    var light = new THREE.DirectionalLight( 0xffffff, 2 );
    light.position.set( 1, 1, 1 );
    scene.add( light );
}

这是我要问的简化版本。我已经阅读了很多文档和论坛,但是在任何地方都找不到。

如果我在函数内部创建“ var light”并将其值分配为“ new”,它将创建对象权限。因为我在函数“ init”的内部声明了它,所以它是局部变量。我了解到javascript中的对象是通过引用传递的。因此,如果我通过“ scene.add(light);”将其添加到场景中,为什么它仍然起作用?我通过了引用,然后对象本身应该被销毁,当我在“ init”之外调用render函数时,它应该失败,对吗?

我的问题是,如果“ new”关键字以某种方式使局部变量即使在函数体结束时仍保持不变,则在仍然保留引用的情况下使该对象保持活动状态?

我说对了吗?

2 个答案:

答案 0 :(得分:2)

尽管变量light在函数中声明,并且在退出后不再存在。变量引用的对象使用scene.add(light)“添加到场景”,并可能创建对该对象的第二个引用。函数退出后,第一个引用light会超出范围并删除该引用,从而使该引用离开scene.add(light)

JavaScript垃圾回收只会在没有引用的情况下清除对象。

new除了创建对象的新实例外,没有什么特别的事情。

答案 1 :(得分:0)

  

如果我在函数内部创建“ var light”并将其值分配为“ new”,   会创建对象吗?

是的

  

由于我在函数“ init”的内部声明了它,因此它是局部变量。我了解到javascript中的对象是通过引用传递的。

如果您的意思是“引用”(例如C和C ++引用),则不会。如果您的意思是像Java中那样,那么可以。有人称其为“引用副本”,就像传递指针一样 到对象。

  

所以如果我通过以下方式将其添加到场景中   “ scene.add(light);”,为什么它仍然有效?我通过了参考,然后   对象本身应该被销毁,当我调用render时   “ init”之外的函数应该失败吧?

该对象不是在堆栈上创建的,只有指向它的值在堆栈中。该对象在堆上创建。由于已将对象传递给另一个方法,因此假设该方法将引用存储在某个地方,则退出此函数时该对象仍将存在。只有变量(包含“指针”)会超出范围。

  

我的问题是,如果“ new”关键字以某种方式使局部变量   即使函数的主体结束时仍然存在,从而使对象保持活动状态   仍然有提及它的东西吗?

当不再有对象引用时(如Java),该对象将被自动垃圾收集(如C中的free)。