const doesn't work in Edge 15 developer tools - javascript

I am running Edge/15.15063. 'Can I Use' says const should work.
Running:
const x = 'woo'
Then:
console.log(x)
Returns
'x' is undefined
Screenshot:
Why isn't const working?

I suspect that the Edge console is using a with statement under its covers like other implementations did. This would explain vars and even function declarations being hoisted outside into the global scope, but let and const will be locked into the block scope:
with (…) {
const x = 'woo'
}
// next input:
with (…) {
console.log(x) // obviously undeclared
}
Try entering them in multiline mode, in a single evaluation - there they should work.
But you also might want to file a bug, as the console is indeed expected to feel like evaluating things in the global scope.

I think I figured this out, but this is as much a guess as an answer. Too long for a comment though.
I think what's happening is that const and let do not create implicit globals when used in the top-level scope in the same way var does. Although top-level variables created with const and let are global, they are not properties of the global window object.
If the MS console is relying on that implicit window property creation for accessing variables created in the console, then const and let will not work.
I am unsure of the inner workings of Chrome Dev Tools, but it seems to create an anonymous function wrapper for code executed in the console:
throw new Error;
VM679:1 Uncaught Error
at anonymous:1:7
(function() { throw new Error; })();
VM759:1 Uncaught Error
at anonymous:1:21
at anonymous:1:33
I am unsure if there is other sandboxing going on here, I didn't necessarily find a lot of documentation on it.

Related

Const is not defined in global scope but defined in local?

Why const is not defined in global scope but defined in local?
screenshoot from devTools
{
console.log(b);
const b = 2;
}
VM366:2 Uncaught ReferenceError: Cannot access 'b' before initialization
at <anonymous>:2:17
console.log(a);
const a = 1;
VM382:1 Uncaught ReferenceError: a is not defined
at <anonymous>:1:13
This seems to be related to some "magic" in how REPL input is handled. It's not really a property of how JavaScript normally works.
If you try this in a node.js file, in a <script>, or even in an (0, eval)('...'), you'll get "Cannot access 'a' before initialization" as expected. Note that even in the DevTools console this won't happen if you are in a paused debugger state.
In a non-paused state (only there), the DevTools allow you to declare variables as if you were continuously writing a script, and the declarations will persist across commands. There is clearly "magic" outside of regular JavaScript involved, because even eval would create another temporary scope. That "magic" is handled by V8 itself. It is therefore pretty likely that whatever trickery is used here has the side effect of this slightly unexpected error. (I initially thought the side effect is that the variable declaration isn't hoisted, but if you do a = 0; const a = 1 then you get "Assignment to constant variable", so that doesn't seem to be the case.)
I tried to trace this to the source, but I got lost in the depths of V8. Nonetheless, I discovered (by opening another DevTools to debug the DevTools themselves!) that this only happens if the replMode argument (that gets passed to the V8 backend's evaluate method) is true. This can be verified by setting a breakpoint here and changing the value of options.replMode.
replMode is documented as follows:
Setting this flag to true enables let re-declaration and top-level await.
Note that let variables can only be re-declared if they originate from replMode themselves.
Hoisting workd differently for const and let than var.
SO for const and let, which are block scoped gives ReferenceError error as they do not initialize value as undefined.
-Whereas, for var it will initialize value as undefinded if you do not assign any v alue and var is function scoped. -You can see console from devToolis giving different error, whereasconsolefromstackoverflow``` giving error as our expectation that
"Uncaught ReferenceError: Cannot access 'a' before initialization.
So I believe it's how devtool console treating the error for block-scope and global-scope.
-Check it on ```morzila-devtool`.
{
console.log("before initialization:" + b);
var b = 2;
console.log("after initialization:" + b);
}
console.log("before initialization:" + a);
const a = 1;
This is from Firefox browser
This is from Microsoft Edge
I came to know from this post that, Chrome and IE both have a global event object. So when we are trying to access it first hoisting won't work for const and let. so it's says that we cannot access but window object has access to those variables, So I assume it's throwing error for a is not defined for window object, which is global object.
window object sets automatically to undefind. const window.variable = undefined (when not defined);
Try to run this code:
{console.log(b); var b=1; console.log(window.c); const c=1;}
OUTPUT:
1 debugger eval code:1:9
undefined // window.c = undefined
And as window object has access to global scope it gives error for a or b or variable is not defined when we access it in global scope before initialisation using let or const.

Why aren't my function's variables available in my promise's callback? [duplicate]

With this code:
function baz() {
var x = "foo";
function bar() {
debugger;
};
bar();
}
baz();
I get this unexpected result:
When I change the code:
function baz() {
var x = "foo";
function bar() {
x;
debugger;
};
bar();
}
I get the expected result:
Also, if there is any call to eval within the inner function, I can access my variable as I want to do (doesn't matter what I pass to eval).
Meanwhile, Firefox dev tools give the expected behavior in both circumstances.
What's up with Chrome that the debugger behaves less conveniently than Firefox? I have observed this behavior for some time, up to and including Version 41.0.2272.43 beta (64-bit).
Is it that Chrome's javascript engine "flattens" the functions when it can?
Interestingly if I add a second variable that is referenced in the inner function, the x variable is still undefined.
I understand that there are often quirks with scope and variable definition when using an interactive debugger, but it seems to me that based on the language specification there ought to be a "best" solution to these quirks. So I am very curious if this is due to Chrome optimizing further than Firefox. And also whether or not these optimizations can easily be disabled during development (maybe they ought to be disabled when dev tools are open?).
Also, I can reproduce this with breakpoints as well as the debugger statement.
I've found a v8 issue report which is precisely about what you're asking.
Now, To summarize what is said in that issue report... v8 can store the variables that are local to a function on the stack or in a "context" object which lives on the heap. It will allocate local variables on the stack so long as the function does not contain any inner function that refers to them. It is an optimization. If any inner function refers to a local variable, this variable will be put in a context object (i.e. on the heap instead of on the stack). The case of eval is special: if it is called at all by an inner function, all local variables are put in the context object.
The reason for the context object is that in general you could return an inner function from the outer one and then the stack that existed while the outer function ran won't be available anymore. So anything the inner function accesses has to survive the outer function and live on the heap rather than on the stack.
The debugger cannot inspect those variables that are on the stack. Regarding the problem encountered in debugging, one Project Member says:
The only solution I could think of is that whenever devtools is on, we would deopt all code and recompile with forced context allocation. That would dramatically regress performance with devtools enabled though.
Here's an example of the "if any inner function refers to the variable, put it in a context object". If you run this you'll be able to access x at the debugger statement even though x is only used in the foo function, which is never called!
function baz() {
var x = "x value";
var z = "z value";
function foo () {
console.log(x);
}
function bar() {
debugger;
};
bar();
}
baz();
Like #Louis said it caused by v8 optimizations.
You can traverse Call stack to frame where this variable is visible:
Or replace debugger with
eval('debugger');
eval will deopt current chunk
I've also noticed this in nodejs. I believe (and I admit this is only a guess) that when the code is compiled, if x does not appear inside bar, it doesn't make x available inside the scope of bar. This probably makes it slightly more efficient; the problem is someone forgot (or didn't care) that even if there's no x in bar, you might decide to run the debugger and hence still need to access x from inside bar.
Wow, really interesting!
As others have mentioned, this seems to be related to scope, but more specifically, related to debugger scope. When injected script is evaluated in the developer tools, it seems to determine a ScopeChain, which results in some quirkiness (since it's bound to the inspector/debugger scope). A variation of what you posted is this:
(EDIT - actually, you mention this in your original question, yikes, my bad!)
function foo() {
var x = "bat";
var y = "man";
function bar() {
console.log(x); // logs "bat"
debugger; // Attempting to access "y" throws the following
// Uncaught ReferenceError: y is not defined
// However, x is available in the scopeChain. Weird!
}
bar();
}
foo();
For the ambitious and/or curious, scope (heh) out the source to see what's going on:
https://github.com/WebKit/webkit/tree/master/Source/JavaScriptCore/inspector
https://github.com/WebKit/webkit/tree/master/Source/JavaScriptCore/debugger
I suspect this has to do with variable and function hoisting. JavaScript brings all variable and function declarations to the top of the function they are defined in. More info here: http://jamesallardice.com/explaining-function-and-variable-hoisting-in-javascript/
I bet that Chrome is calling the break point with the variable unavailable to the scope because there is nothing else in the function. This seems to work:
function baz() {
var x = "foo";
function bar() {
console.log(x);
debugger;
};
bar();
}
As does this:
function baz() {
var x = "foo";
function bar() {
debugger;
console.log(x);
};
bar();
}
Hope this, and / or the link above helps. These are my favorite kind of SO questions, BTW :)
I seem to have access to _this. Where this is undefined in chrome inspector for me, _this seems to reference the appropriate context (and is probably what's used to as > local > this in the stack trace inspector?).
I know this is a bit old, but my issue was minification using babel - i.e. --presets minify
When my js code was built and minified my local variables were undefined; when not minified I was able to see values of variables in the console.

AngularJs: Uncaught ReferenceError: $scope is not defined in debugger mode [duplicate]

With this code:
function baz() {
var x = "foo";
function bar() {
debugger;
};
bar();
}
baz();
I get this unexpected result:
When I change the code:
function baz() {
var x = "foo";
function bar() {
x;
debugger;
};
bar();
}
I get the expected result:
Also, if there is any call to eval within the inner function, I can access my variable as I want to do (doesn't matter what I pass to eval).
Meanwhile, Firefox dev tools give the expected behavior in both circumstances.
What's up with Chrome that the debugger behaves less conveniently than Firefox? I have observed this behavior for some time, up to and including Version 41.0.2272.43 beta (64-bit).
Is it that Chrome's javascript engine "flattens" the functions when it can?
Interestingly if I add a second variable that is referenced in the inner function, the x variable is still undefined.
I understand that there are often quirks with scope and variable definition when using an interactive debugger, but it seems to me that based on the language specification there ought to be a "best" solution to these quirks. So I am very curious if this is due to Chrome optimizing further than Firefox. And also whether or not these optimizations can easily be disabled during development (maybe they ought to be disabled when dev tools are open?).
Also, I can reproduce this with breakpoints as well as the debugger statement.
I've found a v8 issue report which is precisely about what you're asking.
Now, To summarize what is said in that issue report... v8 can store the variables that are local to a function on the stack or in a "context" object which lives on the heap. It will allocate local variables on the stack so long as the function does not contain any inner function that refers to them. It is an optimization. If any inner function refers to a local variable, this variable will be put in a context object (i.e. on the heap instead of on the stack). The case of eval is special: if it is called at all by an inner function, all local variables are put in the context object.
The reason for the context object is that in general you could return an inner function from the outer one and then the stack that existed while the outer function ran won't be available anymore. So anything the inner function accesses has to survive the outer function and live on the heap rather than on the stack.
The debugger cannot inspect those variables that are on the stack. Regarding the problem encountered in debugging, one Project Member says:
The only solution I could think of is that whenever devtools is on, we would deopt all code and recompile with forced context allocation. That would dramatically regress performance with devtools enabled though.
Here's an example of the "if any inner function refers to the variable, put it in a context object". If you run this you'll be able to access x at the debugger statement even though x is only used in the foo function, which is never called!
function baz() {
var x = "x value";
var z = "z value";
function foo () {
console.log(x);
}
function bar() {
debugger;
};
bar();
}
baz();
Like #Louis said it caused by v8 optimizations.
You can traverse Call stack to frame where this variable is visible:
Or replace debugger with
eval('debugger');
eval will deopt current chunk
I've also noticed this in nodejs. I believe (and I admit this is only a guess) that when the code is compiled, if x does not appear inside bar, it doesn't make x available inside the scope of bar. This probably makes it slightly more efficient; the problem is someone forgot (or didn't care) that even if there's no x in bar, you might decide to run the debugger and hence still need to access x from inside bar.
Wow, really interesting!
As others have mentioned, this seems to be related to scope, but more specifically, related to debugger scope. When injected script is evaluated in the developer tools, it seems to determine a ScopeChain, which results in some quirkiness (since it's bound to the inspector/debugger scope). A variation of what you posted is this:
(EDIT - actually, you mention this in your original question, yikes, my bad!)
function foo() {
var x = "bat";
var y = "man";
function bar() {
console.log(x); // logs "bat"
debugger; // Attempting to access "y" throws the following
// Uncaught ReferenceError: y is not defined
// However, x is available in the scopeChain. Weird!
}
bar();
}
foo();
For the ambitious and/or curious, scope (heh) out the source to see what's going on:
https://github.com/WebKit/webkit/tree/master/Source/JavaScriptCore/inspector
https://github.com/WebKit/webkit/tree/master/Source/JavaScriptCore/debugger
I suspect this has to do with variable and function hoisting. JavaScript brings all variable and function declarations to the top of the function they are defined in. More info here: http://jamesallardice.com/explaining-function-and-variable-hoisting-in-javascript/
I bet that Chrome is calling the break point with the variable unavailable to the scope because there is nothing else in the function. This seems to work:
function baz() {
var x = "foo";
function bar() {
console.log(x);
debugger;
};
bar();
}
As does this:
function baz() {
var x = "foo";
function bar() {
debugger;
console.log(x);
};
bar();
}
Hope this, and / or the link above helps. These are my favorite kind of SO questions, BTW :)
I seem to have access to _this. Where this is undefined in chrome inspector for me, _this seems to reference the appropriate context (and is probably what's used to as > local > this in the stack trace inspector?).
I know this is a bit old, but my issue was minification using babel - i.e. --presets minify
When my js code was built and minified my local variables were undefined; when not minified I was able to see values of variables in the console.

Why does Chrome debugger think closed local variable is undefined?

With this code:
function baz() {
var x = "foo";
function bar() {
debugger;
};
bar();
}
baz();
I get this unexpected result:
When I change the code:
function baz() {
var x = "foo";
function bar() {
x;
debugger;
};
bar();
}
I get the expected result:
Also, if there is any call to eval within the inner function, I can access my variable as I want to do (doesn't matter what I pass to eval).
Meanwhile, Firefox dev tools give the expected behavior in both circumstances.
What's up with Chrome that the debugger behaves less conveniently than Firefox? I have observed this behavior for some time, up to and including Version 41.0.2272.43 beta (64-bit).
Is it that Chrome's javascript engine "flattens" the functions when it can?
Interestingly if I add a second variable that is referenced in the inner function, the x variable is still undefined.
I understand that there are often quirks with scope and variable definition when using an interactive debugger, but it seems to me that based on the language specification there ought to be a "best" solution to these quirks. So I am very curious if this is due to Chrome optimizing further than Firefox. And also whether or not these optimizations can easily be disabled during development (maybe they ought to be disabled when dev tools are open?).
Also, I can reproduce this with breakpoints as well as the debugger statement.
I've found a v8 issue report which is precisely about what you're asking.
Now, To summarize what is said in that issue report... v8 can store the variables that are local to a function on the stack or in a "context" object which lives on the heap. It will allocate local variables on the stack so long as the function does not contain any inner function that refers to them. It is an optimization. If any inner function refers to a local variable, this variable will be put in a context object (i.e. on the heap instead of on the stack). The case of eval is special: if it is called at all by an inner function, all local variables are put in the context object.
The reason for the context object is that in general you could return an inner function from the outer one and then the stack that existed while the outer function ran won't be available anymore. So anything the inner function accesses has to survive the outer function and live on the heap rather than on the stack.
The debugger cannot inspect those variables that are on the stack. Regarding the problem encountered in debugging, one Project Member says:
The only solution I could think of is that whenever devtools is on, we would deopt all code and recompile with forced context allocation. That would dramatically regress performance with devtools enabled though.
Here's an example of the "if any inner function refers to the variable, put it in a context object". If you run this you'll be able to access x at the debugger statement even though x is only used in the foo function, which is never called!
function baz() {
var x = "x value";
var z = "z value";
function foo () {
console.log(x);
}
function bar() {
debugger;
};
bar();
}
baz();
Like #Louis said it caused by v8 optimizations.
You can traverse Call stack to frame where this variable is visible:
Or replace debugger with
eval('debugger');
eval will deopt current chunk
I've also noticed this in nodejs. I believe (and I admit this is only a guess) that when the code is compiled, if x does not appear inside bar, it doesn't make x available inside the scope of bar. This probably makes it slightly more efficient; the problem is someone forgot (or didn't care) that even if there's no x in bar, you might decide to run the debugger and hence still need to access x from inside bar.
Wow, really interesting!
As others have mentioned, this seems to be related to scope, but more specifically, related to debugger scope. When injected script is evaluated in the developer tools, it seems to determine a ScopeChain, which results in some quirkiness (since it's bound to the inspector/debugger scope). A variation of what you posted is this:
(EDIT - actually, you mention this in your original question, yikes, my bad!)
function foo() {
var x = "bat";
var y = "man";
function bar() {
console.log(x); // logs "bat"
debugger; // Attempting to access "y" throws the following
// Uncaught ReferenceError: y is not defined
// However, x is available in the scopeChain. Weird!
}
bar();
}
foo();
For the ambitious and/or curious, scope (heh) out the source to see what's going on:
https://github.com/WebKit/webkit/tree/master/Source/JavaScriptCore/inspector
https://github.com/WebKit/webkit/tree/master/Source/JavaScriptCore/debugger
I suspect this has to do with variable and function hoisting. JavaScript brings all variable and function declarations to the top of the function they are defined in. More info here: http://jamesallardice.com/explaining-function-and-variable-hoisting-in-javascript/
I bet that Chrome is calling the break point with the variable unavailable to the scope because there is nothing else in the function. This seems to work:
function baz() {
var x = "foo";
function bar() {
console.log(x);
debugger;
};
bar();
}
As does this:
function baz() {
var x = "foo";
function bar() {
debugger;
console.log(x);
};
bar();
}
Hope this, and / or the link above helps. These are my favorite kind of SO questions, BTW :)
I seem to have access to _this. Where this is undefined in chrome inspector for me, _this seems to reference the appropriate context (and is probably what's used to as > local > this in the stack trace inspector?).
I know this is a bit old, but my issue was minification using babel - i.e. --presets minify
When my js code was built and minified my local variables were undefined; when not minified I was able to see values of variables in the console.

Why can't google chrome's debugger access all the variables? [duplicate]

With this code:
function baz() {
var x = "foo";
function bar() {
debugger;
};
bar();
}
baz();
I get this unexpected result:
When I change the code:
function baz() {
var x = "foo";
function bar() {
x;
debugger;
};
bar();
}
I get the expected result:
Also, if there is any call to eval within the inner function, I can access my variable as I want to do (doesn't matter what I pass to eval).
Meanwhile, Firefox dev tools give the expected behavior in both circumstances.
What's up with Chrome that the debugger behaves less conveniently than Firefox? I have observed this behavior for some time, up to and including Version 41.0.2272.43 beta (64-bit).
Is it that Chrome's javascript engine "flattens" the functions when it can?
Interestingly if I add a second variable that is referenced in the inner function, the x variable is still undefined.
I understand that there are often quirks with scope and variable definition when using an interactive debugger, but it seems to me that based on the language specification there ought to be a "best" solution to these quirks. So I am very curious if this is due to Chrome optimizing further than Firefox. And also whether or not these optimizations can easily be disabled during development (maybe they ought to be disabled when dev tools are open?).
Also, I can reproduce this with breakpoints as well as the debugger statement.
I've found a v8 issue report which is precisely about what you're asking.
Now, To summarize what is said in that issue report... v8 can store the variables that are local to a function on the stack or in a "context" object which lives on the heap. It will allocate local variables on the stack so long as the function does not contain any inner function that refers to them. It is an optimization. If any inner function refers to a local variable, this variable will be put in a context object (i.e. on the heap instead of on the stack). The case of eval is special: if it is called at all by an inner function, all local variables are put in the context object.
The reason for the context object is that in general you could return an inner function from the outer one and then the stack that existed while the outer function ran won't be available anymore. So anything the inner function accesses has to survive the outer function and live on the heap rather than on the stack.
The debugger cannot inspect those variables that are on the stack. Regarding the problem encountered in debugging, one Project Member says:
The only solution I could think of is that whenever devtools is on, we would deopt all code and recompile with forced context allocation. That would dramatically regress performance with devtools enabled though.
Here's an example of the "if any inner function refers to the variable, put it in a context object". If you run this you'll be able to access x at the debugger statement even though x is only used in the foo function, which is never called!
function baz() {
var x = "x value";
var z = "z value";
function foo () {
console.log(x);
}
function bar() {
debugger;
};
bar();
}
baz();
Like #Louis said it caused by v8 optimizations.
You can traverse Call stack to frame where this variable is visible:
Or replace debugger with
eval('debugger');
eval will deopt current chunk
I've also noticed this in nodejs. I believe (and I admit this is only a guess) that when the code is compiled, if x does not appear inside bar, it doesn't make x available inside the scope of bar. This probably makes it slightly more efficient; the problem is someone forgot (or didn't care) that even if there's no x in bar, you might decide to run the debugger and hence still need to access x from inside bar.
Wow, really interesting!
As others have mentioned, this seems to be related to scope, but more specifically, related to debugger scope. When injected script is evaluated in the developer tools, it seems to determine a ScopeChain, which results in some quirkiness (since it's bound to the inspector/debugger scope). A variation of what you posted is this:
(EDIT - actually, you mention this in your original question, yikes, my bad!)
function foo() {
var x = "bat";
var y = "man";
function bar() {
console.log(x); // logs "bat"
debugger; // Attempting to access "y" throws the following
// Uncaught ReferenceError: y is not defined
// However, x is available in the scopeChain. Weird!
}
bar();
}
foo();
For the ambitious and/or curious, scope (heh) out the source to see what's going on:
https://github.com/WebKit/webkit/tree/master/Source/JavaScriptCore/inspector
https://github.com/WebKit/webkit/tree/master/Source/JavaScriptCore/debugger
I suspect this has to do with variable and function hoisting. JavaScript brings all variable and function declarations to the top of the function they are defined in. More info here: http://jamesallardice.com/explaining-function-and-variable-hoisting-in-javascript/
I bet that Chrome is calling the break point with the variable unavailable to the scope because there is nothing else in the function. This seems to work:
function baz() {
var x = "foo";
function bar() {
console.log(x);
debugger;
};
bar();
}
As does this:
function baz() {
var x = "foo";
function bar() {
debugger;
console.log(x);
};
bar();
}
Hope this, and / or the link above helps. These are my favorite kind of SO questions, BTW :)
I seem to have access to _this. Where this is undefined in chrome inspector for me, _this seems to reference the appropriate context (and is probably what's used to as > local > this in the stack trace inspector?).
I know this is a bit old, but my issue was minification using babel - i.e. --presets minify
When my js code was built and minified my local variables were undefined; when not minified I was able to see values of variables in the console.

Categories

Resources