Quirks and workarounds
Iodide runs your JavaScript code by sending it to an iframe and calling the standard JavaScript eval
function on that code. We intentionally evaluate code in the simplest way possible so that your JS code will behave the same way in Iodide as it would if you just ran it in your browser within a normal HTML script
tag. For the most part, this works as expected, however there are a couple quirks that come from using eval
rather than a plain script
tag, and there are also a few JavaScript quirks that you are more likely to encounter while exploring code in Iodide than you would be if you were writing a script for a webpage. This page collects explanation of these quirks, and workarounds whenever possible.
Please also read our page about workflow tips and tricks to get the most out of Iodide.
Variable declarations and scope ("why aren't my variables visible in the global scope?")
If you declare variables in a JavaScript code chunk using the let
or const
keyword, those variables will not be accesible to code in other js
chunks, not will those variables be visible in the environment pane. Variables declared using var
, however, will not suffer this restriction, and neither will variables defined without an explicit declaration keyword.
This is a result of JavaScript's somewhat arcane scoping rules and the way that Iodide executes javascript code, which uses JavaScript's eval
functionality:
- variables defined without a declaration are available in the global scope.
- variables defined with a var
declaration are available within the nearest enclosing function scope. JS eval
does not create a function scope, and because Iodide evaluates code in the global scope, variables created at the top level of a code chuck with a var
declaration are available in the global scope.
- variables defined with let
and const
are avaible within the nearest enclosing block scope. JS eval
does create a block scope, so variables created within a code chunk using these declarations will not be usable outside of the chunk.
While using global variables is rightly discouragedin application development, for exploratory scientific scripting it is normally acceptable. Thus, in Iodide it is often preferable to define variables without explicit declarations or to use var
. However, there are times when you might want to prevent variables defined in the top level of acode chunk from "leaking" out into your global evaluation scope. In these cases, using let
and const
declarations can confine data to a particular scope and help keep your workspace tidy.
Plain object literals in a chunk ("Why can't I run a js chunk containing just {a:1, b:2}
?")
When you are working on a project, it can be useful to create a temporary object to be returned from a code chunk for the sole purpose of using the object inspector in the console to explore some data. The obvious way to accomplish this would be to have a minimal js
code chunk like the following:
%% js
{a: variable_1, b: variable_2, c: variable_3}
However, if you attempt to run a chunk like this that contains a plain object literal, you will get the error message SyntaxError: unexpected token: ':'
.
This is because in JavaScript, a curly brace at the start of a statement creates a block statement.
To accompish the objective above, you need to do something to prevent the JavaScript parser from seeing the opening curly brace as the start of a block statement. You could create an assignment statement (using let
will prevent the variable from leaking into the global scope, see the section above):
%% js
let foo = {a: variable_1, b: variable_2, c: variable_3}
Or could could also wrap the object literal in parenthesis:
%% js
({a: variable_1, b: variable_2, c: variable_3})
Tip: if your objective is to explore your data, remember to check out the Workspace Pane!