In python _ is used as a throwaway variable. Is there an idiomatic accepted name in javascript?
Rigth now, you can use array destructuring, no need for a var.
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Destructuring_assignment
For example:
[,b] = [1,2];
console.log(b);
will output :
2
And the value 1 won't be assigned to any unused var.
There isn't an accepted throwaway variable naming in JavaScript like in Python. Although, generally in the software engineering world, engineers tend to call those variables:
dummy, temp, trash, black_hole, garbage.
Use these variable namings or whatever name that will imply to the engineer reading your code that these variables have no specific use.
With that in mind, I would strongly not recommend using signs such as below as a throwaway variable:
_, $
Unless there is an explicit convention like in Python, don't use these signs as a throwaway variable, otherwise, it may interfere with other naming conventions and libraries in other languages, like the underscore and the jQuery libraries in JS.
And of course, if you find a specific use for that variable later on, make sure to rename it.
Generally, you will declare the signature of a function as an array. Simply omit one of them
const foo = (bar,baz,) => bar+baz;
foo(3,4,5) // → 7
This obviously works as long as the declaration of function argument is the last one; unlike this answer, which is valid for already-declared variables embedded in arrays. This:
const foo = (, bar,baz) => bar+baz;
will fail with:
Uncaught SyntaxError: expected expression, got ','
You can hack your way into this using any expression. However, you'll need to use the self same expression in every invocation
const quux = ([], bar,baz) => bar+baz;
quux(42,3,4); // → Uncaught TypeError: (destructured parameter) is not iterable
quux([],3,4); // → 7
That constant can be anything, so you can as well call it "dummy", but you will still have to repeat in every invocation.
Related
I'm trying to read through some source code on the internet, and I'm getting confused because the author defined a function as:
var _0x80a1 = function (x, a) {...}
But then only calls it using statements like this:
_0x80a1("0x0")
How does that work?
JavaScript parameters are optional you don't need to pass them. So you can do something like this:
function multiply(a, b) {
if(typeof b === 'undefined') {
b = 10;
}
return a * b;
}
console.log(multiply(5));
// expected output: 50
In newer versions of JS you can also do default parameters like this:
function multiply(a, b = 10) {
return a * b;
}
console.log(multiply(5));
// expected output: 50
No function "requires" an argument in JavaScript. It's not a strongly typed language.
I might be typing out of my own butt, but I think function's arguments are syntactic sugar in JS. You can always pass any amount of arguments, regardless of the function's "signature", because the only thing that identifies a function in JS, is its name (and the object on which it is called). That is why, the arguments object exists.
So, as others pointed it out, the second, third, or any other argument that wasn't given will simply be undefined.
An answer on this subject with examples
In ,JavaScript function parameters are optional.If your'e not making use of 'a' inside your function then JS compiler don't care about that.If your'e making use of 'a' inside your function then you will encounter some error like "a is undefined".
function (x,a=10){
}
You can set default parameters like this.Now even if your'r passing one parameter to your function it will run without any errors
I was curious so tried to understand this a bit so I could try to answer.
The variable _8x80a1 is a literal bit definition (https://www.hexadecimaldictionary.com/hexadecimal/0x80A1/) representing e.g. 32929 in decimal.
I'm guessing JS internally numbers all functions when its run. This leaves an entire integer (32766) 'vanilla' functions that can be compiled before using a literal as a function name might cause a conflict.
So the 'x' in the function def. looks like it's passing a string, but it might be just calling 'Function #0' in the _8x80a1 var/function. This would make sense if the function contains multiplpe 'sub functions', as then the 'a' variable can be an object collection (e.g. parameters), that can be passed to the sub-function.
Roughtly, I think .. Not used JS for a whilst and just thought I'd try to help answer! ;-) Essentially a compact way to make a toolkit you can copy between projects, and know your references will all work as expected to your tools, without disrupting e.g. jQuery or other scripts. (Wouldn't be surprised if this is how JS is minified actually ;)).
Chris
Please consider this snippet:
let variableName = 'internalVariable';
{
let internalVariable = 'whatever';
console.log(eval(propertyKey)); // prints 'whatever'
}
What are my options to accessing internalVariable via the string stored in variableName? I was hoping for something like scope[variableName], but there seems to be nothing like it.
Given this particular scenario, are there any alternatives to using eval?
In situations where dynamic access to something like a variable is required, the idiomatic thing to do is employ an object and dynamically compute property names as appropriate.
var obj = {};
obj[getPropertyName()] = "hello world";
Variables declared in functions with var, let, or const do exist as properties of something like an object (the closure of a function call), but JavaScript does not provide any way of referring to that thing as an object. Using eval() is possible, but generally it's a bad idea because runtime optimization is not attempted in modern runtime systems because eval() makes that intractably complicated.
The only way a variable is aliased in JavaScript is via the arguments object, and that's sufficiently weird that it's explicitly discouraged in "strict" mode.
[edit] — in re: Bergi's comment below, the (generally deprecated) with statement allows implicit references to object properties, and the export mechanism for modules can create aliases, though to me it's hard to imagine that being a good thing in actual practice.
In Javascript, local variables do not live on any object that I'm aware of. That is,
function foo() {
const x = 2;
self.x; // undefined
this.x; // undefined
window.x; // undefined
x; // 2, obviously
eval('x'); // 2
}
The last option eval('x') shows that it is possible to refer to these variables by name. I'm looking to extend this and access a variable using a name pattern:
function foo() {
// Code not under my direct control
function foobar_abc() {}
function other_functions() {}
// Code under my control
const matchingFunction = // find the function with name matching 'foobar_*'
}
If this lived on an object, I would use something like myObject[Object.keys(myObject).find((key) => key.startsWith('foobar_'))]. If it were in the global scope, myObject would be window and everything works.
The fact that eval is able to access the variable by name implies that the value is available somewhere. Is there any way to find this variable? Or must I resort to techniques which re-write the (potentially very complex) code which is not under my direct control?
I'm targeting modern browsers, and in this use case I don't mind using eval or similarly hacky solutions. Arbitrary code is already being executed, because the execution of user-provided code is the purpose.
Another option is to use code parsing to deduce the function names using a javascript AST (abstract syntax tree) library. The "esprima" package will probably be good place to look:
https://www.npmjs.com/package/esprima
So you can do
import esprima from 'esprima'
const userCodeStructure = esprima.parseScript( userProvidedJavascriptString );
const allTopLevelFunctionDeclarations = userCodeStructure.body.filter( declaration => declaration.type === "FunctionDeclaration" );
const allTopLevelFunctionNames = allTopLevelFunctionDeclarations.map( d => d.id );
I haven't tried this myself by the documentation suggests it should work (or something like it):
http://esprima.readthedocs.io/en/latest/
One possible approach that might help you here is to evaluate at global scope rather than in a function, and that might put the functions on the window object instead of in local scope.
Easiest way to do this is probably to write a new tag into the document and inject the user-provided code.
Relying on variable names is the wrong approach.
eval is evil. It may not be available under CSP. Considering that the code is supposed to run in browser, the biggest problem is that variables don't have expected names in minified code. They are a, b, c...
In order to maintain their names, they should be object properties - and so they will be available on the object.
Or must I resort to techniques which re-write the (potentially very complex) code
This is refactoring and that's what should be done to avoid bad code that smells and creates major problems.
I find myself, for reasons which are too irrelevant to go into here but which involve machine-generated code, needing to create variables with names which are Javascript reserved words.
For example, with object literals, by quoting the keys if they're invalid identifiers:
var o = { validIdentifier: 1, "not a valid identifier": 2 };
Is there a similar technique which works for simple variable references?
A poke around the spec shows that there used to be a mechanism that allowed this, by abusing Unicode escapes:
f\u0075nction = 7;
However this seems incredibly dubious, and is apparently rapidly vanishing (although my recent Chrome still appears to support it). Is there a more modern equivalent?
If they're object keys, you can call them what you like (even reserved names), and you don't need to quote them.
var o = { function: 'a' }
console.log(o.function) // a
DEMO
Is there a more modern equivalent?
No. Reserved words cannot be used as variable names. You can use names that look like those words but that's it.
From the spec:
A reserved word is an IdentifierName that cannot be used as an Identifier.
FYI, reserved words can be used as property names, even without quotes:
var o = { function: 1 };
Variable names can't be reserved words.
You can always do bad things like:
window["function"] = 'foo';
console.log(window.function);
> foo
You still can't reference it using a bare reserved, because it's reserved.
That it's machine-generated code means whatever is generating the code is broken.
To create an IDE that would autocomplete all variables the user declares but would be oblivious to other variables such as Math.PI or even the module Math, the IDE would need to be able to identify all identifiers relating to variables declared by the user. What mechanism could be used to capture all such variables, assuming you already have access to the AST (Abstract Symbol Table) for the program?
I am using reflect.js (https://github.com/zaach/reflect.js) to generate the AST.
I think it's pretty much impossible
Here is why I think it's pretty much impossible without executing it:
Let us go through the unexplored parts, from easy to hard.
Easy to catch:
Function scope is missed here:
(function(x){
//x is now an object with an a property equal to 3
// for the scope of that IIFE.
x;
})({a:3});
Here is some fun dirty tricks for you all.:
Introducing... drum roll... Block Scoping!!
with({x:3}){
x;//x is now declared in the scope of that with and is equal to 3.
}
try{ throw 5}catch(x){
x // x is now declared in the scope of the try block and is equal to 5;
}
(people reading: I beg you to please not use these last two for actual scoping in code :))
Not easy:
Bracket notation:
var n = "lo";
a["h"+"e"+"l"+n] = "world"; // need to understand that a.hello is a property.
// not a part of the ast!
The really hard parts:
Let us not forget invoking the compiler These would not show up in the AST:
eval("var x=5"); // declares x as 5, just a string literal and a function call
new Function("window.x = 5")();// or global in node
In node.js this can also be done with the vm module. In the browser using document.write or script tag injection.
What else? Of course they can obfuscate all they want:
new Function(["w","i","n","dow.x"," = ","5"].join(""))(); // Good luck finding this!
new Function('new Function(["w","i","n","dow.x"," = ","5"].join(""))()')();// Getting dizzy already?
So what can be done?
Execute the code, once, in a closed, timed environment when you update the symbol table (just the relevant parts)
See what's the generated symbol table is from the execution
Boom, you got yourself a symbol table.
This is not reliable but it's probably as close as you get.
The only other alternative I can think of, which is what most IDEs are doing is to simply ignore anything that is not:
object.property = ... //property definition
var a = ... //scoped
b = ... //global, or error in strict mode
function fn(){ //function declaration
object["property"] //property with a _fixed_ literal in bracket notation.
And also, function parameters.
I have seen no IDE that has been able to deal with anything but these. Since they're the most common by far, I think it's perfectly reasonable to count those.
By adding them onto am object that already exists....ie
window.mynewvar = 5;
function mynewfunc() {
}