views:

61

answers:

2

If I need to see if a certain value is in a string, is it better for performance to use the .test() method or the .search() method?

Example with .search():

var myRegExp = '/Orange/',
    myString = 'This is a string with the word "Orange."';

if(myString.search(myRegExp) != -1) {
    // Do code here
}

Example with .test():

var myRegExp = '/Orange/',
    myString = 'This is a string with the world "Orange."';

if(myRegExp.test(myString)) {
    // Do code here
}

Ultimately, what I'm doing is searching for a specific class name in string. The element would contain multiple classes, so I'd need to find if one of the classes is in it.

Example Markup:

<ul>
    <li class="expandable expanded">
        <ul>
            <li>Text</li>
        </ul>
    <li>
    <li class="expandable collapsed">
        <ul>
            <li>Text</li>
        </ul>
    </li>
</ul>

So, I'm adding a click event to the list items, if they have the class name "expanded" they need to behave one way, if they have the class name "collapsed" they need to behave another.

So, essentially, something like this.

element.addEventListener('click',function(e) {
    if( /* e.target has class name of expanded */ ) {
        // Do certain code
    } else {
        // Do other code
    }
}

I am using jQuery, and I am open to suggestions, but I feel this situation would be better served with native javascript. So, which method would give the best performance? Or is there another method that would be even better?

+2  A: 

Well, if you are using jQuery, you can do this simply with

element.addEventListener('click',function(e) {
    if( $(e.target).hasClass('expanded' ) {
        // Do certain code
    } else {
        // Do other code
    }
}

If you don't want to create a jQuery object for whatever reason (e.g. performance) you could use this function, adapted from the source of $().hasClass():

function hasClass ( el, selector ) {
    var className = " " + selector + " ";

    if ( (" " + el.className + " ").replace(/[\n\t]/g, " ").indexOf( className ) > -1 ) {
        return true;
    }

    return false;
}

You can then call this like so:

if ( hasClass(e.target, 'expanded') ) {

Personally, I would go for the jQuery approach if you already have it loaded.

lonesomeday
Well, I have the library loaded, but the page is pretty script intensive, so I'd like to optimize every last bit of performance I can. What this does tell me, though, is that instead of .test() or .search(), the jQuery team decided to use .indexOf() to see if the value is in the string or not, which I hadn't thought of, and may be the best performance route.
RussellUresti
@RusselUrest What this answer should be telling you is: don't worry about doing this yourself, just use the `hasClass()` function
Josh Stodola
A comparison between jQuery and pure JS solutions: http://jsperf.com/pure-js-hasclass-vs-jquery-hasclass @Josh This function is not the same as the jQuery hasClass function -- it doesn't require a jQuery selector object.
lonesomeday
@lonesomday Regardless, it is redundant. He has the jQuery library loaded, there is no reason to roll your own function that performs an identical task.
Josh Stodola
@Josh Well, performance -- not requiring a jQuery selection should be faster (slightly). (I wrote the test wrong originally, hence the odd performance stats in Chrome.)
lonesomeday
@Josh Having the library available doesn't mean you have to use everything it offers. Native JS is sometimes faster than using jQuery wrappers because, often, jQuery will call a function that calls a function that calls a function that finally performs some code and returns a value -- this can add unnecessary execution time. When you have a library, you shouldn't use it as a crutch; if there is a more efficient way to do something, use that.
RussellUresti
@RusselUresti @lonesome I find it funny that we are discussing Javascript performance, all the while you are ignoring the fact that including the library adds significant weight to your pages. Re-writing existing functions adds *even more* weight. That weight is far more detrimental than any execution speeds. Where do you think performance matters most, with the client CPU or with their Internet connection? The answer is *obvious*.
Josh Stodola
lonesomeday
@Josh I'm not sure we have the same definition of "performance". Adding the library would only cause an additional file to be loaded on page load, and if you load that through a CDN the browser will use an extra thread, so page load time wouldn't increase that much at all. Or you could lazy load the script after the page is finished loading, so the library wouldn't affect initial page load at all. Meanwhile, if you have a script intensive site, every interaction the user has will cause additional performance delays if you write your code poorly. I'm talking execution time, not page load time.
RussellUresti
+1  A: 

test() returns true or false. search() returns the position of the match, or -1 if no match is found.

So, i think test() would be faster.

mac
Yep, through testing, it turns out test() is faster than search(). test() against indexOf() though is a bit more unclear. indexOf() is faster for most browsers by about 10%, but in Chrome, test() is faster by over 50%, so I guess it depends on who uses your site.
RussellUresti
Nice, every little performance increase helps.
mac