What is the ??! operator in Javascript? - javascript

when I'm looking for some sites Javascript code, I see this
function hrefLeftMenu() {
var x = true;
for (i in info) {
$(".leftmenu ul").append("<li" + (x ? " class='active'" : "") + " onclick='openAnInfo(\"" + i + "\", this);'> - " + info[i].title + "</li>");
x = x??!x;
}
openAnInfo("0", ".lelelesakineyy");
}
What it does in javascript? Why the coder's used this operator?
Thanks.

What it does in javascript?
It throws a syntax error.
> x = x??!x;
SyntaxError: Unexpected token ?
Why the coder's used this operator?
Taking a reasonable guess (beyond "they made a mistake") would need more context. Saying for sure would require mind reading :)

In JavaScript this is not valid code. However, the sequence ??! exists (existed?) in C as a trigraph, representing |. Maybe that's not JavaScript code, or it was poorly-ported from ancient C code. But even then, x = x | x can hardly be called a useful statement.
EDIT: With a bit context in the question now, that speculation is likely wrong. A friend suggested that maybe the sequence x?? was a typo and subsequent attempt to correct it where backspace was turned into a character by some intermediate mangling (not uncommon when typing in terminals or via SSH) and that the line in question was supposed to be x = !x.

I think it is a mistake. They're generating a menu and x is used to set an item as active, and it looks like they want to default to selecting the first item. They want x to be true the first time around, and then false for the rest. It was probably supposed to be something like
x = x?!x:x; // If first time through, then set x = false for the rest
aka
x = false; // Set x = false for the rest
but confusion/muddy thinking led to over-complification.

Was this a mistake?
Did you mean this?
x= x?x:!x;

Related

How to insert parentheses in an eval statement to order operations in JavaScript?

This is the Code Sandbox: https://codesandbox.io/s/rw0j2orqmp
The file this is in is reducers.js
I'm building a React/Redux calculator app, and currently I'm in the process of making the output display the results of the current calculation held in state. It works without parentheses but calculates the whole formula rather than a piece at a time. To fix this I wanted to wrap each piece in parentheses to have it calculate separately, taking off the method and then sticking it back on when the first part is finished calculating by doing this:
value:
methods.indexOf(state.lastValue) < 0
? eval("(" + state.calc.slice(0, -1) + ")" + state.calc.slice(-1) + state.value)
: state.value,
but when I have it like that, I get "Unexpected token ) " .
Is there an easier way to accomplish what I'm trying to do, and or is there a functional replacement for eval() in this case?
I'm not sure why you're using eval or parentheses here. Is there a reason why this won't work for you?:
methods.indexOf(state.lastValue) < 0
? state.calc.slice(0, -1) + state.calc.slice(-1) + state.value
: state.value
If you need to group things together, just use parentheses without the eval.
methods.indexOf(state.lastValue) < 0
? ((state.calc.slice(0, -1)) + state.calc.slice(-1) + state.value)
: state.value
Update: I see what you're saying, sorry, it was hard to understand from your original explanation and I was on my mobile and couldn't really inspect your sandbox.
I'm thinking it may be better to keep a string that you can evaluate simply later, for example, if you have "7 + 3" stored and press *, turn wrap that original string in parentheses and add the *, resulting in "(7 + 3) *", etc. Then whenever you want to show the result, you just evaluate that single stored calculation.
If you insist on doing eval that way, I'll just tell you that it works. For example, try this in the console:
eval("(" + "7 + 3" + ")" + "* 2")
// 20
So you may be doing something wrong with the values you are returning from the slice, which results in an eval error.
Try console logging that whole expression to see what's actually going on.

JSLint confusion in Javascript alerts are not declared

Hey so I'm using JSLint under the assumption I'm using a browser and tolerating multiple vars and whitespace mess.
The whole program works, but I have a few problems, according to JSLint. First off, I'm trying to use alert(string) to make pop-up error messages, but JSLint is telling me the alerts are undeclared, I haven't found a resource on the internet that's explained how to make this not happen yet.
Secondly, I have loops that look like this:
function setMixedList() {
"use strict";
clearResults();
var n = "0";
var l = "0";
var text = "";
while (n < numList.length && l < letList.length) {
document.getElementById("listInput").value =
text += numList[n] + letList[l];
n ++;
l ++;
}
This loop in particular takes two separate arrays and mixes them together in order; one containing numbers (1-7) and the other containing letters (a-g) in a way so they appear in a text box like this:
1 a 2 b 3 c 4 d 5 e 6 f 7 g
JSLint doesn't like two things about this. The first is that in the
document.getElementById("listInput").value =
text += numList[n] + letList[l];
section of the loop, JSLint tells me the "+=" is unexpected. When I edit that to:
text = text + numList[n] + letList[l];
JSLint tells me the "=" is unexpected and I'm not sure how to take these things out without making my program unable to work.
The other important part of this is the
n ++;
l ++;
section of code. I know JSLint doesn't like ++, but if I make the code
n+= 1;
l+= 1;
The string doesn't come out right, with some characters undefined because I'm not just dealing with numbers. Anybody know how to fix these problems?
To answer the first part
JSLint is telling me the alert
This can be resolved by following one of the way . In jslint options set
"devel:true" which will enables things like Alert, console,prompt.Check this link to know more about it.
Secondly set browser option set to true in your .jshintrc and use window.alert instead of alert

JavaScript indexOf() Method giving -1 when decimal value is present in array

I'm having some trouble with the JavaScript indexOf() Method. I have an array...
pointLatArray = new Array();
When I try to get the index of a variable that I know is present in the array it returns -1, which I know normally indicates to the value not being found. When my code is as follows..
setlat = 52.6688391881732;
pointArrayIndex = pointLatArray.indexOf(setlat);
console.log(setlat + " " + pointLatArray[8] + " " + pointArrayIndex);
I get the following logged to console.....
04-16 12:35:31.370: D/CordovaLog(7048): 52.6688391881732 52.6688391881732 -1
However when I change the code by replacing setlat with pointLatArray[8] in the following line....
pointArrayIndex = pointLatArray.indexOf(pointLatArray[8]);
the following gets logged to console where it displays the correct index of 8 instead of -1 as expected.......
04-16 12:46:17.230: D/CordovaLog(8497): 52.6688391881732 52.6688391881732 8
Is it because I'm using such a long decimal set as the variable setlat? If so, or for what ever reason if anyone could suggest a fix I would appreciate it very much.
Many thanks
Strict comparison for double numbers is not a good idea. Probably what you observe here is rounding error. Although the numbers seem to be the same to you they may differ by a small epsylon.
One option I see is to use custom indexOf function using epsylon comparison(i.e. allow numbers to differ by a small value. For instance 0.000000000001 or 1e-12).

Is it safe to run code inside the conditional operator?

I often see and use codes like:
var myvar = (1 < 2) ? 3 : 4 ; //if 1 < 2 then myvar = 3, else = 4
But I just recently saw a code that was executing code, just like some kind of replacement for the if(){}else{}:
Example:
(1 < 2) ? alert("example1") : alert("example2");
The first thoughts that came to me were, "wow, this is like 6-7 characters shorter", "endless of possibilities" or "this made my day".
My question:
Is this thing error-free and safe to use? (like, with a lot of code inside, and nested stuff)
For now, I will just keep using it in the normal way, I have the fear that if I start using it to execute pieces of code might not work.
Is this thing error-free and safe to use? (like, with a lot of code
inside, and nested stuff)
Yes. However, the more code that's within it, the less readable it becomes.
I prefer to use it (the conditional operator) for short, concise statements. Anything more complex deserves an if/else for the sake of readability and maintainability.
There are some exceptions. You can't do this with:
break
continue
Any block like if, for, while, do, or try
for example. What's more, it can mess with your order of operations:
x < 3 ? l = true : r = true; // Syntax error, = has lower precedence than ?:
But that's not the reason not to do it, it's because it's ugly. Which one is clearer to you, this:
if(i > 5) {
alert('One');
} else {
alert('Two');
}
or
i > 5 ? alert('One') : alert('Two');
? It's not quite right, is it? And saving characters is never a reason to do anything, really; otherwise there would be no comments or whitespace. A good minifier like Google Closure Compiler will automatically convert these for you when possible, and there are plenty of other places to save. In the end, it's just whatever you find most convenient and readable.
Also, if you do end up needing break, continue, etc. then it's going to be rather inconsistent and unattractive code.
You're referring to the ternary operator. It's usually used for setting variables with simple strings like this:
var phone = old ? "blackberry" : "iPhone"
That much simpler than using an if:
var phone = "iphone"
if (old) {
phone = "blackberry"
}
It's good in this context, in the example you described and as soon as it starts getting confusing or I'd definitely not recommend it!
Your example might be made better like this:
var msg = 1 < 2 ? "alert1" : "alert2";
alert(msg);
You could also write:
alert( 1<2? "example1" : "example2" );
The ternary opertator is designed for simple cases, sometimes developers get carried away and use it to replace multiple if..else statements, e.g.
var someVal = foo < bar? 'yes' : bar > fum? : fum : fi != fee? fi : fee;
which is not a good idea IMHO.

XML stores text data with double quotes, JavaScript crashes when retrieving data

I am not sure I am going to be able to explain this one right as it may be difficult for me to explain, but I am going to try.
I have a web form which it publish the data to a XML file, then it shows the data in another web page.
Everything works fine, but when the user types a double quote character, at the time the web page try to display the data it crashes due to the double quote symbol, which it make sense as it may be considered as an unfinished string by javascript.
There is also something it is worth mention, and that is that the problem only occurs on a section of the form, where consist of a table which its populated with an array created based of a collection of elements from the XML and then insert the text from the array to the table cells using the innerHTML.
eg.
XML
<node1>
<node2> test "1</node2>
</node1>
<script type="text/javascript">
alert("<xsl:value-of select="node1/node2">");
<script>
This will not work, maybe if I get any workaround to this, I can fix the rest.
Sorry guys if I have not explain myself well enough, I don't know how to expose this problem any better. I would be happy to answer any question if you need it.
Please, note that if any of you have any answer, it has to be javascript, no jquery.
Thanks.
Always escape user input. Your bug is a benign example of the problems that can occur, but it means you're also probably vulnerable to a code injection attack, such as cross-site scripting.
Escaping
Here's what Wikipedia has to say about escaping. Here's an overly-simplified example of what it means. Assume that you have the following JavaScript and that I haven't made any silly errors in it (since I just made it up):
function unsafeAlert() {
alert("You shouldn't be doing this!\n" + document.getElementsById('userInputField').value);
}
What happens if the user types in something like '); document.forms[0].action="http://www.example.com/maliciousPage.html";document.forms[0].submit();"? Suddenly, your alert causes the form (which might contain sensitive data) to be submitted to an attacker's page. This is obviously a problem. You should have some library code somewhere that escapes the value before you attempt to alert it. This will do things like putting slashes in front of quotes, etc. Also, you probably shouldn't try to write such code yourself, since escaping logic is always at least 10 times harder than you think it will be. You should definitely be getting logic like this from a library somewhere.
Right guys,
I have been playing around, and found a way to fix it.
using the following function.
XML
<node1>
<node2>test "1</node2>
</node1>
<script type="text/javascript">
function convertString(value){
for(var z=0; z <= value.length -1; z++)
{
//if current character is a backslash
if(value.substring(z, z + 1)=="\\" && (value.substring(z, z + 4)!="\\r\\n" && value.substring(z, z + 2)!="\\n"))
{
value = value.substring(0, z) + "\\\\" + value.substring(z + 1, value.length);
z++;
}
if(value.substring(z, z + 1)=="\\" && value.substring(z, z + 4)=="\\r\\n")
{
z = z+4;
}
if(value.substring(z, z + 1)=="\\" && value.substring(z, z + 2)=="\\n")
{
z = z+2;
}
}
//replace " with \"
//loop through each character
for(var x = 0; x <= value.length -1; x++){
//if current character is a quote
if(value.substring(x, x + 1)=="\""){
//concatenate: value up to the quote + \" + value AFTER the quote
value = value.substring(0, x) + "\\\"" + value.substring(x + 1, value.length);
//account for extra character
x++;
}
}
//return the modified string
return(value);
}
<script>
alert("<xsl:value-of select="convertString(string(node1/node2))"/>");
Thanks to everyone who answered in this question.

Categories

Resources