Home > Software engineering >  For aggregating elements at an array instance within a constructor can `[].push.apply(this, arr)` be
For aggregating elements at an array instance within a constructor can `[].push.apply(this, arr)` be

Time:09-24

This line in my constructor function takes 0.15ms to execute.

[].push.apply(this, selector);

Please don't tell me 0.15ms time is acceptable. I am hoping there is some faster option.

Because I think this line is converting NodeList/HTMLCollection to array. I don't necessarily need to convert it to array. This is why, I think it can be replaced with something else. Can you think of?

(function () {
    'use strict';
    
    function Query(selector) {
        if (selector.indexOf('.') !== -1) {
            selector = document.querySelectorAll(selector);
        }
        else {
            selector = document.getElementsByTagName(selector);
        }
        
        [].push.apply(this, selector);
    }
    
    function $(selector) {
        return new Query(selector);
    }
    
    
    Query.prototype = new Array;
    Query.prototype.hide = function () {
        for (var i=0,len=this.length;  i<len;  i  ) {
            this[i].style.display = 'none';
        }
        return this;
    };
    
    
    window.$= $;
}());

CodePudding user response:

Following suggestions of @SebastianSimon this[0] = selector[0]; and @PeterSeliger this.push(...selector);in comments, I thought idea of for-loop.

After some testing, I found it faster than "[].push.apply(this, selector);".

I will take more experienced developers suggestion on it.

(function () {
    'use strict';
    
    function Query(selector) {
        if (selector.indexOf('.') !== -1) {
            selector = document.querySelectorAll(selector);
        }
        else {
            selector = document.getElementsByTagName(selector);
        }
        
        //[].push.apply(this, selector);
        var i=0,  len=selector.length;
        for (;  i<len;  ) {
            this[i] = selector[i  ];
        }
        this.length = len;
    }
    
    function $(selector) {
        return new Query(selector);
    }
    
    
    Query.prototype = new Array;
    Query.prototype.hide = function () {
        for (var i=0,len=this.length;  i<len;  i  ) {
            this[i].style.display = 'none';
        }
        return this;
    };
    
    
    window.$= $;
}());

CodePudding user response:

(function () {

  'use strict';

  class Query extends Array {

    constructor(selector) {
      super();

      this.push(...document.querySelectorAll(selector));
    }
    hide() {
      for (var idx = 0, len = this.length;  idx < len; idx  ) {
        this[idx].style.display = 'none';
      }
      return this;
    }
    show() {
      for (var idx = 0, len = this.length;  idx < len; idx  ) {
        this[idx].style.display = '';
      }
      return this;
    }
  }

  function $(selector) {
    return new Query(selector);
  }
  window.$ = $;

}());

const query = $('span');

setTimeout(() => query.hide(), 1000);
setTimeout(() => $('.quick-fox > span').show(), 2000);

setTimeout(() => console.log({ query }), 3000);
setTimeout(() => console.log('query.push(...$("p")) ...', query.push(...$("p"))), 4000);
setTimeout(() => console.log({ query }), 5000);
<p class="foo-bar">
  <span>foo</span>
  <span>bar</span>
  <span>baz</span>
</p>

<p class="quick-fox">
  <span>The</span>
  <span>quick</span>
  <span>brown</span>
  <span>fox</span>
</p>

  • Related