Is this required or (||) statement?

The last code here is from underscore, on line 211, which reads

result || (result = iterator.call(context, value, index, list))) return breaker; 

required or required instruction? It can be replaced by

 (result = iterator.call(context, value, index, list))) return breaker; // ? 

result initially set to false, and does not change anywhere in the code except this one line.

Note that the JavaScript or (||) operator returns the first operand if it is true, and the second operand if it ('he' is the first operand) is false. This is straight from Crockford Good Parts. It is also noted that || has a value of true or false with true / false.

Here is the whole method reproduced from the link above:

 var any = _.some = _.any = function(obj, iterator, context) { iterator || (iterator = _.identity); var result = false; if (obj == null) return result; if (nativeSome && obj.some === nativeSome) return obj.some(iterator, context); each(obj, function(value, index, list) { if (result || (result = iterator.call(context, value, index, list))) return breaker; }); return !!result; }; 
+4
source share
2 answers

It makes me think that checking result|| just in case ... or to support environments where forEach defined (for example, using a pad), but some not.

As noted in the comments, emphasizing the dependency on your own looping methods ( forEach , map and friends) doesn't seem like a brilliant idea for several reasons:

  • they are slower than simple loops
  • you can't break (well, you could with a highlighted exception, but underlining doesn't)
  • Array.prototype may be modified by other (malicious or stupid) code
+7
source

Answer: Yes , it can be optimized by the proposed method , if it was native code .

To understand what will happen, simplify this code, which is important here, first:

 var result = false; for (var i in obj) { if (result || (result = call(i))) return; } 

This means that if either result no longer false, it will return, or if call() returns the wrong value, it will return. Since the result changes only to call() , the first check on result is redundant.

 var result = false; for (var i in obj) { if (result = call(i)) return; } 

This code will still be returned as soon as call() delivers the wrong value.

In addition, since each() is a library function, and the OP returns a breaker on the found element

what really happens:

 var result = false; for (var i in obj) { if (result || (result = call(i))) break; } 

In this case, the code can still be optimized by the proposed method if the library foreach function is used. The cycle will be left at the found value.

The confusing part is that each() is a library function and uses a function to simulate a loop body. Returning the breaker library constant from the body function will exit the loop.

Once each() decides to use its own .forEach() , the code can no longer be optimized , since .forEach() will not understand the return value of breaker ! See thg435's answer for details!

+3
source

Source: https://habr.com/ru/post/1488696/


All Articles