Variable assignment in if statement - javascript

In Swift we can assign a variable as we evaluate the existence of a potential value, such as:
if let x = y {
// do something with x
}
Is there an equivalent in JavaScript?

There's no such equivalent solution in JavaScript, because there's no equivalent problem.
What you're demonstrating is conditional binding, which exists to allow you to create a non-optional value (x, in your example), out of an optional value (y). There's no such need in Javascript, because all values are nullable, for better or for worse.
You just do a null check, like so:
if (y) {
}
Just as how you shouldn't write JavaScript code in Swift, you shouldn't write Swift code in JavaScript. It's a completely different languages, with completely different features, syntax, patterns and designs.

Related

How to pass javascript property (name) without using hard coded String?

Example use case:
I have an object with an attribute "myProperty", having getter and setter ("Property Getters and Setters" are supported since EcmaScript 5: https://www.w3schools.com/js/js_es5.asp):
var obj = {
myProperty:'myPropertyValue',
get myProperty(){
return this.property;
},
set myProperty(value){
this.property=value;
}
};
I would like to bind that attribute to a view, which is the task of a custom function that is called bindProperty.
In order to pass the property myProperty to the function, I could do something like
bindProperty(obj, 'myProperty');
However, I would like to avoid to pass the property name as a hard coded String. Strings have the disadvantage, that they are not updated when the attribute name changes during refactoring.
If I would use
bindProperty(obj, obj.myProperty);
the function would only know the property value 'myPropertyValue' and not where the value comes from.
=>How can I pass/identify the property itself, without using a String?
A. Using reflection?
I could imagine something like
bindProperty(obj, ()=>obj.myProperty);
The function bindProperty would then have to do some reflection magic to find out the name of the attribute in the body of the lambda expression (pseudo code):
let attributeName = getNameofArgumentFromBodyOfLambdaExpression(lambda);
obj[attributeName] = 'newValue';
=>Is it possible in JavaScript to evaluate the body of the lambda expression using reflection to get the name of the property?
(I know that this can be done in .NET languages, e.g.
Private Sub BindProperty(Of T)(propertyExpression As Expression(Of Func(Of T)))
Dim propertyName As String = GetPropertyName(propertyExpression)
'...
)
B. Using complex attributes
An alternative whould be that I use wrapping property objects, having their own getters and setters. Howerver, then I would have to use the property like
obj.myProperty.set('newValue')
or
obj.myProperty('newValue') //similar to knockout observables
I still want to be able to use the great Getter/Setter feature. With other words: I want to use my properties like plain attributes:
obj.myProperty = 'newValue'
Therefore, this is not an option for me and I would prefer to use Strings instead of B.
C. Any other alternatives?
An object in javascript is more or less just a mapping of strings or symbols to values. There is no real reflection that you can call upon in the runtime environment that would enable you to move backward from the value to the property name.
If all you need is refactoring, the one way to do this would be to just configure your IDE to recognize string accessors by providing some sort of type information either via Flow or Typescript or something of that sort (the type information is likely what allows reflection to work in languages like .NET). Or you could just settle for a unique prefix like "viewable_propName" and just do simple find and replace if you need to rename.
If you are really focused on getting this to work without type information and in current ES6 syntax, you could do the following:
function getNameofPropFromVal(obj, val){
for(let prop in obj){
if(obj[prop] === val) return prop;
}
}
obj[getNameofPropFromVal(obj, obj.myProp)] = 'newVal';
Though this has shortcomings:
(1) There is no guarantee that two properties won't share the same value.
(2) It introduces unnecessary runtime overhead.
Finally, if you're willing to be cutting edge and use a transformer like babel you could use decorators for your bindProperty method. That way you can just do the binding in the object definition itself. Here is an article explaining the gist and here is the more formal ECMAScript proposal.
I just found following simple work around that might fullfill my needs:
function bindProperty(obj, lambdaExpression){
let expression = lambdaExpression.toString(); // "()=> obj.myProperty"
let subStrings = expression.split(".");
let propertyName = subStrings[1];
console.info(propertyName );
//...
}

Searching local javascript variables by name patterns

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.

Building a LINQ-like query API in JavaScript

I'd like to write a JavaScript class that works like C#'s IQueryable<T> interface to enable nicely-formatted queries against a remote data source. In other words, I'd like to be able to write the following (using ES6 arrow syntax):
datasource.query(Sandwich)
.where(s => s.bread.type == 'rye')
.orderBy(s => s.ketchup.amount)
.take(5)
.select(s => { 'name': s.name });
and turn that into something like
SELECT s.name AS name
FROM sandwich s
JOIN bread b ON b.sandwich_id = s.id
JOIN ketchup k on k.sandwich_id = s.id
WHERE b.type = 'rye'
ORDER BY k.amount
LIMIT 5;
with the SQL query (or whatever query language is used) being actually sent to the server. (Doing the filtering on the client side is not feasible because the server might return tons of data.)
In C#, this functionality is supported by the Expression class, which lets you construct an expression tree from a lambda function. But JavaScript has no equivalent, as far as I know. My original plan was to feed f.toString() to Esprima's parser for the function f passed as the argument to select(), where(), etc. and use that expression tree. This approach works great as long as the expressions refer only to literals, but when you try something like
var breadType = 'rye';
datasource.query(Sandwich)
.where(s => s.bread.type == breadType)
...
it fails, because you'll have a token breadType that you can't replace with a value. As far as I can tell, JavaScript has no way to introspect the function closure and get the value of breadType after the fact externally.
My next thought was that since Esprima will give me a list of tokens, I could modify the function body in-place to something like
return {
'breadType': breadType
};
and then call it, taking advantage of the fact that even if I can't access the closure, the function itself can. But modification of a function's code in-place also seems to be impossible.
Another approach that would not require Esprima would be to pass in a sentinel object as the argument to the inner function f and override its comparison operators, which is how SQLAlchemy's filter() works in Python. But Python provides operator overloading and JavaScript does not, so this also fails.
This leaves me with two inferior solutions. One is to do something like this:
var breadType = 'rye';
datasource.query(Sandwich)
.where(s => s.bread.type == breadType)
.forValues(() => {
'breadType': breadType
});
In other words, I could force the caller to provide the closure context manually. But this is pretty lame.
Another approach is to do the sentinel object thing but with functions instead of operators since operators can't be overloaded:
var breadType = 'rye';
datasource.query(Sandwich)
.where(s => s.bread.type.equals(breadType));
ES6's Proxy objects will make this simple to implement, but it's still not as good as the version with regular operators.
Sorry for the long post. My ultimate question is whether it's possible to achieve this with the ideal syntax shown in the first code block and, if so, how to do it. Thanks!
No, this is indeed impossible for the reasons you outlined. If you want to support passing arbitrary closures as arguments, then your only choice is to execute the functions. You cannot transform them to SQL statements, at some degree this will always fail regardless how many static code analysis you perform on the files.
I guess your best bet here are template literals, where you could have something like
var breadType = 'rye';
datasource.query(Sandwich, `
.where(s => s.bread.type == ${breadType})
.orderBy(s => s.ketchup.amount)
.take(5)
.select(s => { 'name': s.name })
`)
so that you can keep your syntax as you want, but will have to supply all external variables explicitly.

How to use typed variables in javascript?

Is there any way to use typed variables in javascript? Like integer, string, float...
JavaScript variables are not typed.
JavaScript values are, though. The same variable can change (be assigned a new value), for example, from uninitialized to number to boolean to string (not that you'd want to do this!):
var x; // undefined
x = 0; // number
x = true; // boolean
x = "hello"; // string
Javascript is dynamically typed, whereas other languages, C# and Java for example, are statically typed. This means that in Javascript variables can be reassigned to values of any type, and thus that you don't ever need to explicitly denote the type of variables or the return type of functions. If you saw code like this in a statically typed language
int x = 5;
x = "hello";
you would rightfully expect the compiler to start throwing up a big nasty TypeError. Javascript, on the other hand, will happily run this code even though the type changed.
var x = 5;
x = "hello";
Because variables can change types, the compiler can't know as much information about them. You should expect the tools for Javascript to be inferior to those of Java/C# as far as useful niceties like code completion go. Fewer mistakes will be caught at compile time and you will have to do more runtime debugging than you are probably used to.
That said, this also allows you to be more free with your variables and you can change types at will, which can often be convenient. You can write code like this if you want:
var x; //typeof x === "undefined"
x = "Hello, world!"; //typeof x === "string"
x = 42; //typeof x === "number"
x = false; //typeof x === "boolean"
x = {}; //typeof x === "object"
Not possible in Javascript, but if you really need it, you should check TypeScript. It is a superset of Javascript that adds optional static typing. It also has class-based programming.
One of the main characteristics of Javascript is that it is weak typed language. Why do you need strong types anyways?
I recommend you read this:
http://en.wikipedia.org/wiki/Strong_typing
javascript is a weak and dynamic type..it's dynamic because the variable type is determine in the runtime, and is loosely type because you can perform this operation for example
var letter = "2";
var number = 2;
console.log(letter+number);
this in java, c# or any other static and stricted type language will make an error but in javascript you get a "22" as result (it is because javascript is weak typed or loosely typed)
now..you've other languages than keep use typed values, like clojure or dart, where for performance reasons, you can use functions or methods with typed arguments, javascript doesn't let this and only accept dynamic values, like ruby...
I hope this help and you can understand my poor english :D
People writing "why shouldn't use it / you shouldn't use it" are wrong. In the next Java Script 2.x specification there is a plan to add strong typed variables.
Meanwhile you may use very simple solution to emulate strong types:
var = Object.create( String );
After that autocompleting in a lot of IDE (including IntelliJ IDEA) will work great and you have declared and initialized an object of specified type.
Read more on my blog.
There is a simple hack to simulate typed variables in Javascript using typed arrays.
var a = new Int8Array(1);
a[0]=5;
a[0]=~a[0]; // -6
var b = new Uint8Array(1);
b[0]=5;
b[0]=~b[0]; // 250
The only useful reason I know for ever doing this is when you need to use bitwise operations on an unsigned integer when translating code from a typed language which has to do exactly the same in Javascript. Javascript integers are signed by default and bitwise operations can mess up the sign.
Creating a typed array for just a single variable is generally not good for the performance.
Often...
var b=5;
b=(~b)&0xff; // 250
will do the trick just fine and only 32-bit unsigned integers need to be typed in Javascript to avoid problems with bitwise operations.
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Typed_arrays#Typed_array_views
Javascript is a loosely typed language, so no, there aren't types as you are used to in some other languages.
you can use TypeScript for definition types for values
While JavaScript is not explicitly a typed language, it's like a typeless filling in a language sandwich with stronger-typed representations above (in the IDE) and below (in the compiler.) To support IDE-friendly and optimizer-friendly code, there are a number of tricks you can use to obtain explicit types.
JavaScript implementations include just-in-time compilers (JITs) to convert JavaScript into fast machine language. One of the tricks they use is to convert it into an intermediate, strongly typed form. If your goal is performance, you can make life easier by favoring const variables and coercing types into more explicit types.
For example, JavaScript supports two number types outside of typed arrays: 64-bit Float (a.k.a. double) and 32-bit integer. While double is the default, you can coerce a number into an integer with |0, like this:
const myInt = 3.0 | 0;
You see this pattern a lot in high-performance code, particularly stuff that was written before typed arrays.
The other reason to have explicit types is to make life easier for developers. Microsoft invented TypeScript so that IDEs (particularly their Visual Studio) can provide code completion, refactoring (in particular renaming), and error detection. It does this by being a strongly typed language. One of the language goals for TypeScript is to provide a future direction for JavaScript. Because of this goal TypeScript is a superset of JavaScript and no features are added to TypeScript that couldn't be in a future JavaScript release. Similarly, if future versions of JavaScript break TypeScript, TypeScript will be changed to match JavaScript.
TypeScript isn't JavaScript, so why do I bring it up? Because even if you aren't using it, your editor may be. Since TypeScript is a superset of JavaScript, the TypeScript compiler can parse JavaScript—and produce type information for all the functions and variables. So if you use Visual Studio, WebStorm, or an editor with a TypeScript plugin, you get type information even with pure JavaScript! (The smarter ones will warn you if you use TypeScript features in JavaScript.)
In fact, one of the arguments against using TypeScript I've heard recently is that JavaScript editors have gotten so good (thanks to the embedded TypeScript compiler) that the advantages no longer outweigh the burden of having another language.
However, to have strong typing (from the IDE's perspective) it helps to make it easy for the compiler to guess how your source files connect together, favor consts, and avoid writing functions that return more than one type.
<html>
<head>
<meta charset="utf-8">
<title>JS_Byte</title>
<script>
class Byte
{
constructor(Value)
{
this.Number = new Uint8Array(1);
this.Number[0] = Value;
}
get Get()
{
return this.Number[0];
}
set Set(newValue)
{
this.Number[0] = newValue;
}
};
//On load
function Load_Page()
{
let Byte_Num = new Byte(12);
document.write(Byte_Num.Get.toString() + "<br>");// -> 12
Byte_Num.Set = 14;
document.write(Byte_Num.Get.toString() + "<br>");// -> 14
Byte_Num.Set = 256;
document.write(Byte_Num.Get.toString() + "<br>");// -> 0
}
</script>
</head>
<body onload="Load_Page()">
</body>
</html>

Dynamic vs Static Compiler (JavaScript)

I'm currently writing a JavaScript compiler in ANTLR+Java.
I've read questions here on Stack Overflow on how to proceed with the execution - and the answer is always that it would be way too hard to do a static compilation (without JIT-information) of a dynamic language - but why is that exactly? There are of course the obvious "type resolving" problem and in JavaScript maybe a problem with the eval function - but are there other reasons? (because they don't seem too hard to overcome pure statically (no JITS))
I'm excluding JIT-based compilation because I figure it would be too hard for me to implement.
I have some experience in writing static compilers with a byte-code execution.
UPDATE:
All your answers are really helpfull understanding the problem.
To clarify does this mean that JavaScript is harder to implement than other dynamic languages?
And does this also means that im better of using a Tree-based interpreter than e.g. Byte-code (if we forget about the property that JS always is shipped in raw source code - hence adding extra time for generating and IR and afterwards execute it)? - or should they be about equally easy / hard to do?
(Im new to SOF; dont know if this is the preferred way to update a question?)
There are lots of ways this conversation could go. Here's one direction. In javascript, nearly everything is an object and properties or methods can be added to any object at run-time. As such, you don't know at compile time what methods or properties will or won't be attached to an object. As such, everything has to be looked up at run-time.
For example:
var myObj = {};
function configureObject() {
if (something in the environment) {
myObj.myfunc = function () {alert("Hi");}
} else {
myObj.myfunc = function () {document.write("Hello");}
}
}
Now, sometime later in the code you call myObj.myfunc(); It is not known at compile time what myfunc is or whether it's even an attribute of myObj. It has to be a run-time lookup.
In another example, take this line of code:
var c = a + b;
What his means depends entirely upon the types of a and b and those types are not known at compile time.
If a and b are both numbers, then this is an addition statement and c will be a number.
If either a or b is a string, then the other will be coerced to a string and c will be a string.
You can't precompile this kind of logic into native code. The execution environment has to record that this is a request for the addition operator between these two operands and it has to (at runtime) examine the types of the two operands and decide what to do.
The challenge with writing a static JavaScript compiler is that it is in general undecidably hard to determine what objects are being referenced at any program point or what functions are being called. I could use the fact that JavaScript is dynamic to decide which function to call based on the output of some Turing machine. For example:
var functionName = RunTuringMachineAndReportOutputOnTape(myTM, myInput);
eval(functionName + "();");
At this point, unless you have advance knowledge about what myTM and myInput are, it is provably impossible to decide what function will be invoked by the call to eval, since it's undecidable to determine what is on a Turing machine's tape if it halts (you can reduce the halting problem to this problem). Consequently, no matter how clever you are, and no matter how good of a static analyzer you build, you will never be able to correctly statically resolve all function calls. You can't even bound the set of functions that might be called here, since the Turing machine's output might define some function that is then executed by the above code.
What you can do is compile code that, whenever a function is called, includes extra logic to resolve the call, and possibly uses techniques like inline caching to speed things up. Additionally, in some cases you might be able to prove that a certain function is being called (or that one of a small number of functions will be called) and can then hardcode in those calls. You could also compile multiple versions of a piece of code, one for each common type (object, numeric, etc.), then emit code to jump to the appropriate compiled trace based on the dynamic type.
V8 does that. See Compile JavaScript to Native Code with V8
With EcmaScript 3 and 5 non-strict there are a number of wrinkles around scopes which you don't run into in other dynamic languages. You might think that it is easy to do compiler optimizations on local variables, but there are edge cases in the language when it is not, even ignoring eval's scope introspection.
Consider
function f(o, x, y) {
with (o) { return x + y + z; }
}
when called with
o = {};
o = { z: 3 };
o = { x: 1, z: 2 };
Object.prototype.z = 3, o = {};
and according to EcmaScript 3,
x = (function () { return toString(); })()
should produce quite a different result from
x = toString();
because EcmaScript 3 defines an activation record as an object with a prototype chain.

Categories

Resources