I´m trying to interpret source codes from big platforms like Facebook to learn how great programmers do their work, some of them have a type of programming that I have been never seen before.
This loop is inside that type of programming:
for (var e; b.length && (e = b.shift()); ) b.length || void 0 === c ? d = d[e] ? d[e] : d[e] = {
}
This is the first time I see something like this, I finally thought that this slice of code was only created for distracting and scare possible malicious users
The loop starts with an undefined variable called 'e'
for (var e;...
And it has no condition to running it, it do nothing, no sense.
b.length && (e = b.shift());
This code means: number of elements inside b and e equals b without the first element
the third loop statement is also empty, there is no increment.
Now the hardcore part, there is no action for every recursion, not even Braces {}
b.length || void 0 === c ? d = d[e] ? d[e] : d[e] = {
}
This code means: number of elements inside b or if undefined equals the content inside the variable c and if d equals the element number e inside d, then do nothing and if not then element number e inside d equals an empty braces {}
As you can see, this code has no sense, it has no reason to exist, but it does, so, Can an expert tell me if this is actually works for something or its just ascii symbols with no utility?
Related
Just read on Javascript book by David Flanagan this case:
(a = b) == 0
But I can't see the use of this. Could be like this?
var b = 0;
var a = b;
if (a == 0) ...
Thanks
Your interpretation is correct. The assignment returns the assigned value.
It just assigns b to a. If b (and consequently a) is 0, the condition is true.
It's evaluated in this order:
(a = b) == 0
-------
^ assign the value of b to a
------------
Check if the value of a equals 0
Pretty much it's the same with:
a = b;
if (a == 0) {
// do something
}
It's just a shorter version. Don't forget to declare the variables, otherwise they will be appended to the global namespace.
This is the short form. Means:
Assign b to a
Then compare the value.
(a = b) assigns b to a and is furthermore an expression with the new value of a.
So (a = b) == 0 is an expression that assigns b to a and is evaluates its relational equality to 0.
In C and C++ you'll often see it written as if (!(a = b)). Some folk find such a form obfuscating as it's a stone's-throw away from the considerably different if(!(a == b)).
An exception occurred several times inside the following function, running in the (Chrome) browsers of our users. NB the code is minified, I've just added newlines for readabilily.
function a(c, b, e, f) {
for (var d in b) {
if (c && _.isObject(b[d]) === true && _.isArray(b[d]) === false) {
a(c[d], b[d], e, d + ".")
} else {
if (!c || _.isEqual(c[d], b[d]) === false) {
e.push({
name: f + d,
value: b[d]
})
}
}
}
return e
}
The exception was: TypeError: Cannot read property 'beginning' of null
So far my analysis is this:
Known fact: beginning is one of the values of the d variable (a
property of b).
So, the exception occurred when evaluating b[d]or c[d]
Inside the for loop, c can be null, but not b (b null => no loop)
So, the only way to trigger that exception is to have a null c
If c is null, we have to take the else path
If c is null, !c is truthy, so _.isEqual(...) should not be evaluated (see Is that js expression safe: if( !x || doSomething( x[prop], y[prop] ) === false )).
At that point, I've reached a dead end in my reasoning. The exception should not happen. I probably made a mistake somewhere along the line, but where ?
NB: the problem seems to be fixed (I can't reproduce it, so I can't be sure), just by changing the code a bit, adding a separate 'is c null ?' test before the if...else, but that's not very satisfying.
I've found this string in JavaScript code.
var c = (a.b !== null) ? a.b : null;
This is a shorthand of an if-else statement, however the value null is assigned if it is null. Isn't that ALWAYS equivalent to
var c = a.b
including all cases - exceptions, null, undefined, etc?
In another words, are these lines (always) equivalent?
var c = (a.b !== null) ? a.b : null;
-vs-
var c = a.b
No, they AREN'T NECESSARILY EQUAL always if b is a getter that updates a variable. It's bad practice to code this way though
var log = 0;
var a = {
get b() {
log++;
return log;
}
}
var c = (a.b !== null) ? a.b : null;
// outputs 2
console.log(c);
var log = 0;
var a = {
get b() {
log++;
return log;
}
}
var c = a.b;
// outputs 1
console.log(c);
These statements are logically equivalent.
That being said, and as mentioned in another answer, if a.b has side effects, the statements will not result in the same program state.
This could be readily obvious in the form of var c having a different value depending on which of these statements are executed, or more hidden, if a.b modifies something elsewhere in the program.
Refactoring
As refactoring has been discussed, I'll touch on it briefly. As the above has hopefully made obvious, directly refactoring would not be safe in all scenarios. However, I would still recommend a refactor of one kind or another.
The two possible situations as I see them are:
a.b has no side effects, direct refactoring is safe
a.b has hidden side effects. This represents very unclear, confusing,
and just downright bad code. It should be refactored so that all
changes happening during the statement are clear and obvious to a
reader (hopefully intuitively so, as well as supported by comments).
As #potatopeelings already pointed out, the two possible statements are not always equivalent, since one can write obscure code, which will have different results.
However, if I see a code, like
var c = (a.b !== null) ? a.b : null;
I will assume that the code's intention is
var c = a.b;
so I will change it to make the code prettier. If I will be negatively surprised, that is, the code does not pass the testing phases due to this change, then I will try to find the author of a.b with git blame.
So, my answer is, that the two statements are not equivalent, but should be equivalent in well-written code.
Well, actually not even
var c = (a !== null) ? a : null;
is guaranteed to be equivalent to
var c = a;
when a is resolved by a getter or an ES6 proxy handler on the global object.
Hence for instance, this assign to c the value 0:
Object.defineProperty(self, 'a', { get: function() { return c ^= 1; } });
var c = (a !== null) ? a : null;
console.log(c);
while this assigns to c the value 1:
Object.defineProperty(self, 'a', { get: function() { return c ^= 1; } });
var c = a;
console.log(c);
You're right, var c = a.b is exactly the same as var c = (a.b !== null) ? a.b : null;
My guess is the null in the ternary operator was meant to be anything except null, a default value if you will.
The reason for that confusingly odd syntax is because a.b might be an empty string OR undefined, and apparently an empty string is valid input.
Also, note: a.b might be a function.
I have little experience in javascript but in other programming languages the following is possible, to set a default value for a missing parameter in a function.
For instance lets say i have a function
function foo(a , b)
return a + b
{
I would like to be able to call the above function with 1 parameter or with 2 parameters
one parameter case:
foo(2) //a =2 and b would be automatically set to a default no argument value,
two parameter case:
foo(1,2) // a = 1 , b = 2 => 3
Is this possible in javascript that is IE 8 compatible or using Jquery 1.7.2?
JavaScript functions allow you to call them with less parameters than specified.
What you're trying to accomplish is possible doing something like the following:
function foo(a , b){
if(typeof b === "undefined"){
b=3;
}
return a + b;
}
foo(5);//return 3;
I strongly suggest that you check for undefined and not rely on the || operator. I've spent hours debugging code that made that assumption and failed when passing 0 or another falsy value. The JavaScript type system can get really tricky, for example "0" is falsy.
ECMAScript Harmony (the next version) allows default parameters like in those other languages using the following syntax
function foo(a , b=3){
return a + b;
}
This does not work in IE8 like the first version though.
No, but you can simulate this effect manually with a tertiary operator or an if statement (just make sure you check for undefined!):
function foo(a, b) {
b = (typeof b === "undefined") ? 2 : b;
return a + b;
}
Yes, it's possible. If a parameter isn't passed, you get a special value "undefined". The following works for me:
function foo(a, b) {
a = a || defaultForA;
b = b || defaultForB;
}
Due to the way Javascript treats conversion to boolean, the following will all be considered undefined in the above code snippet:
undefined
null
0
"" (empty string)
false
So if those values are important to you, you'll need to explicitly test for undefined rather than the blanket "if not false" test being used above.
An undefined parameter evaluates as false, so you can do something like this in the beggining of your function foo:
a = a || 0;
b = b || 0;
That way if a or b exist, they will be evaluated with their own values and with 0 otherwise.
You can just test if you received a parameter:
function foo(a, b) {
if(typeof b === "undefined") {b = 2;}
}
By testing for "undefined" you can also accept parameters that evaluate to false (like null or "" or 0 or false)
What can be the most efficient way to find an item in an array, which is logical and understood by a web developer?
I came across this piece of code:
var inArray = function(a, b, c, d) {
for (c in b) d |= b[c] === a;
return !!d
};
It works fine. Can someone please explain me the code?
I also came across an exact same question that might make mine as a duplicate. But my real question lies in explanation of the above code and why bitwise operator has been used into it.
Also, can there be a way without any for loop, or iteration to get index of an item in an Array?
var inArray = function(a, b, c, d) {
for (c in b) d |= b[c] === a;
return !!d
};
That is some terrible code, and you should run away from it. Bitwise operators are completely unnecessary here, and c and d being parameters makes no sense at all (as Raymond Chen pointed out, the author of the code likely did it to safe space of declaring local variables -- the problem though is that if true is passed in for d the code is suddenly broken, and the extra parameters destroys any sense of understanding that glancing at the declaration would provide).
I'll explain the code, but first, here's a better option:
function inArray(arr, obj) {
for (var i = 0; i < arr.length; ++i) {
if (arr[i] === obj) {
return true;
}
}
return false;
}
Note that this is dependent on the array being an actual array. You could use a for (k in arr) type loop to generalize it to all objects.
Anyway, on to the explanation:
for (c in b) d |= b[c] === a;
This means that for every key in b (stored in c), we will check if b[c] === a. In other words, we're doing a linear scan over the array and checking each element against a.
d |= val is a bitwise or. The bits that are high in val will be set high in d. This is easier to illustrate in languages where bits are more exposed than in JS, but a simple illustration of it:
10011011
01000001
--------
11011011
It's just OR'ing each individual bit with the same location bit in the other value.
The reason it's an abuse here is that it convolutes the code and it depends on weird implicit casts.
x === y returns a boolean. A boolean being used in a bitwise expression makes little sense. What's happening though is that the boolean is being converted to a non-zero value (probably 1).
Similarly, undefined is what d will be. This means that d will be cast to 0 for the bitwise stuff.
0 | 0 = 0, but 0 | 1 = 1. So basically it's a glorified:
for (c in b) d = (d || (b[c] === a));
As for !!x that is just used to cast something to a bool. !x will take x, implicitly cast it to a bool and then negate it. The extra ! will then negate that again. Thus, it's likely implicitly casting to a bool (!!x being true implies that x is at least loosely true (1, "string", etc), and !!x implies that x is at least loosely false (0, "", etc).
This answer offers a few more options. Note though that all of them are meant to fallback to the native indexOf that will almost certainly be faster than anything we can code in script-land.
This code is pretty poorly written, and barely readable. I wouldn't qualify it as "awesome"...
Here's a rewritten version, hopefully more readable:
function inArray (aElt, aArray) {
var key;
var ret = false;
for (key in aArray)
ret = ret || (aArray[key] === aElt);
return ret;
}
The for loop seems like the most natural way to do that. You could do it recursively but that doesn't feel like the easiest approach here.
What can be the most efficient way to find an item in an array, which is logical and understood by a web developer?
Either the native method, haystack.indexOf(needle) !== -1 or a looped method which returns as soon as it can
function inArray(needle, haystack) {
var i = haystack.length;
while (i) if (haystack[--i] === needle) return true;
return false;
};
You asked for a recursive version
var inArray = function(arr, needle, index) {
index = index || 0;
if (index >= arr.length)
return false;
return arr[index] === needle
? true
: inArray(arr, needle, index + 1);
}
console.log(inArray([1,5,9], 9));