Problem/Motivation

When reading through the views code I came accross the
core/modules/views/js/base.js
which contains optimizable for loops:

for(var i in pairs) {  
  if (typeof(pairs[i]) === 'string') {
    ..
  }
}

Which could be done faster with less code
for(var i = 0; i<pairs.length; i++) { .. }
Or even faster but maybe a little bit harder to read
for(var i = pairs.length; i>=0; i--) { .. }

However the real problem is that this loop might cause unintended behaviour if the global Array.prototype is modified:

Array.prototype.hello = "world";
pairs = [];
for(var i in pairs) {  
  if (typeof(pairs[i]) === 'string') {
    console.log(i);
  }
}

So the typeof check is not needed as String.prototype.split always returns an array of strings:
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global...

Some of the above points also apply for the second loop:

for (var i in chars) {
  if (href.indexOf(chars[i]) > -1) {
    ..
  }
}

Proposed resolution

Use for(var i = 0; i<pairs.length; i++) { .. } and remove if (typeof(pairs[i]) === 'string') { so
* it's faster
* requires less code
* is safer

Comments

nod_’s picture

Status: Active » Needs review
Issue tags: +JavaScript

looks ok, needs some testing.

When you fill a JS patch, please tag it JS so we can see it :)

jantimon’s picture

Thanks for your advice and your fast response :)

jantimon’s picture

Any updates on this issue?

jantimon’s picture

views.base_.for-loop.patch queued for re-testing.

dawehner’s picture

Issue summary: View changes
Issue tags: +VDC

Please tag changes in views with VDC

dawehner’s picture

Assigned: Unassigned » nod_

I cannot really review the patch, though I think nod_ can.

damien tournoud’s picture

If we are nitpicking, those two uses of var are strongly discouraged:

+    for (var i = 0; i < pairs.length; i++) {
+      var pair = pairs[i].split('=');

... because they seem to imply that Javascript is block scoped. It is not: it is *function* scoped, so it is best to have all the local variables declared at the top of the function.

jantimon’s picture

Status: Needs review » Reviewed & tested by the community
nod_’s picture

Assigned: nod_ » Unassigned
Status: Reviewed & tested by the community » Needs work

Um unfortunately you're not supposed to RTBC your own issues.

I'm fine with the var i = 0 in the for loop but not on the var pair, can you move the declaration outside the loop please?

Other than that it's fine.

jantimon’s picture

Status: Needs work » Needs review
StatusFileSize
new1.39 KB

Alright - I moved the declaration of pair:

var pair;
    var pairs = query.split('&');
    for (var i = 0; i < pairs.length; i++) {
      pair = pairs[i].split('=');
      // Ignore the 'q' path argument, if present.
      if (pair[0] !== 'q' && pair[1]) {
        args[decodeURIComponent(pair[0].replace(/\+/g, ' '))] = decodeURIComponent(pair[1].replace(/\+/g, ' '));
      }
    }
nod_’s picture

Status: Needs review » Reviewed & tested by the community

Perfect, that works. thanks a lot!

droplet’s picture

Please consider this full rewritten patch #2175513: Handle params array in Drupal.Views.parseQueryString JS function. Of course we can keep the for-loop but while + regex would be more readability & less code.

webchick’s picture

Status: Reviewed & tested by the community » Fixed

Looks like that issue is still needs work, so let's get this one in in the meantime.

Committed and pushed to 8.x. Thanks!

Status: Fixed » Closed (fixed)

Automatically closed - issue fixed for 2 weeks with no activity.