相关疑难解决方法(0)

为什么Chrome调试器认为关闭的局部变量未定义?

使用此代码:

function baz() {
  var x = "foo";

  function bar() {
    debugger;
  };
  bar();
}
baz();
Run Code Online (Sandbox Code Playgroud)

我得到了这个意外的结果:

在此输入图像描述

当我更改代码时:

function baz() {
  var x = "foo";

  function bar() {
    x;
    debugger;
  };
  bar();
}
Run Code Online (Sandbox Code Playgroud)

我得到了预期的结果:

在此输入图像描述

此外,如果eval在内部函数中有任何调用,我可以按照我想要的方式访问我的变量(无论我传递给什么都没关系eval).

同时,Firefox开发工具在两种情况下都给出了预期的行为.

与Chrome有什么关系,调试器的行为不如Firefox?我已经观察了这种行为一段时间,包括版本41.0.2272.43 beta(64位).

是不是Chrome的javascript引擎可以"平坦化"这些功能呢?

有趣的是,如果我添加在内部函数中引用的第二个变量,x变量仍未定义.

我知道在使用交互式调试器时经常有范围和变量定义的怪癖,但在我看来,基于语言规范,应该是这些怪癖的"最佳"解决方案.所以我很好奇这是因为Chrome比Firefox更优化.以及在开发期间是否可以轻松禁用这些优化(也许在开放工具打开时应该禁用它们?).

此外,我可以使用断点和debugger语句重现这一点.

javascript google-chrome google-chrome-devtools

155
推荐指数
3
解决办法
3万
查看次数

如何在JavaScript中运行时表示闭包和作用域

这主要是一个好奇心问题.考虑以下功能

var closure ;
function f0() {
    var x = new BigObject() ;
    var y = 0 ;
    closure = function(){ return 7; } ;
}
function f1() {
    var x = BigObject() ;
    closure =  (function(y) { return function(){return y++;} ; })(0) ;
}
function f2() {
    var x = BigObject() ;
    var y = 0 ;
    closure = function(){ return y++ ; } ;
}
Run Code Online (Sandbox Code Playgroud)

在每种情况下,在执行函数之后,(我认为)无法到达x,因此BigObject可以被垃圾收集,只要x是对它的最后一个引用.只要评估函数表达式,一个简单的解释器就会捕获整个范围链.(首先,你需要这样做来调用eval工作 - 下面的例子).更智能的实现可能会在f0和f1中避免这种情况.更智能的实现将允许保留y,但不保留 …

javascript closures garbage-collection

32
推荐指数
2
解决办法
1635
查看次数

node.js的垃圾收集

我很好奇嵌套函数的node.js模式如何与v8的垃圾收集器一起工作.这是一个简单的例子

readfile("blah", function(str) {
   var val = getvaluefromstr(str);
   function restofprogram(val2) { ... } (val)
})
Run Code Online (Sandbox Code Playgroud)

如果restofprogram长时间运行,这是不是意味着str永远不会被垃圾收集?我的理解是,对于节点,你最终会使用嵌套函数.如果在外部声明restofprogram,这是否会收集垃圾,因此str不在范围内?这是推荐的做法吗?

编辑我不打算让问题复杂化.那只是粗心大意,所以我修改了它.

javascript v8 node.js

29
推荐指数
2
解决办法
1万
查看次数

关于闭包,LexicalEnvironment和GC

作为ECMAScriptv5,每当控件输入代码时,enginge创建一个LexicalEnvironment(LE)和一个VariableEnvironment(VE),对于功能代码,这两个对象是完全相同的引用,它是调用NewDeclarativeEnvironment(ECMAScript v5 10.4)的结果. 3),在函数代码中声明的所有变量都存储在VariableEnvironment(ECMAScript v5 10.5)的环境记录组件中,这是闭包的基本概念.

令我困惑的是Garbage Collect如何使用这种闭包方法,假设我有以下代码:

function f1() {
    var o = LargeObject.fromSize('10MB');
    return function() {
        // here never uses o
        return 'Hello world';
    }
}
var f2 = f1();
Run Code Online (Sandbox Code Playgroud)

在该行之后var f2 = f1(),我们的对象图将是:

global -> f2 -> f2's VariableEnvironment -> f1's VariableEnvironment -> o
Run Code Online (Sandbox Code Playgroud)

从我的小知识来看,如果javascript引擎使用引用计数方法进行垃圾收集,则该对象o至少有1次重新引用,并且永远不会被GCed.显然这会导致浪费内存,因为o永远不会被使用但总是存储在内存中.

有人可能会说引擎知道f2的VariableEnvironment …

javascript closures garbage-collection

13
推荐指数
1
解决办法
691
查看次数

javascript如何在循环内创建变量

var i,j;
for (i=0; i<30; i++) {
    for (j=0; j<10; j++) {
        // do something
    }
}
Run Code Online (Sandbox Code Playgroud)

for (var i=0; i<30; i++) {
    for (var j=0; j<10; j++) {
        // do something
    }
}
Run Code Online (Sandbox Code Playgroud)

由于javascript的范围逻辑,第二种方式创建并销毁了j次30次?我更喜欢使用第一种方式,但我不知道是否存在差异.在那儿?

javascript variables

3
推荐指数
3
解决办法
152
查看次数