views:

236

answers:

6

I need a JavaScript function to tell me whether a string object is empty. By "empty", I mean that it's not all just whitespace characters. I've written this prototype:

String.prototype.isEmpty = function() {
  return this.length === 0 || this === " " || this.test(/^\s*$/);
}

Is this alright?

Is there a more-performant version of this out there?

+3  A: 

It looks like you need to use /^\s*$/.test(this) instead of this.test(/^\s*$/). There is no test() method for strings, unless you're using some JavaScript library that implements this method.

The /^\s*$/.test(this) would have been enough, but the first two expressions would short circuit if any one of them evaluates to true, without having to test the regular expression. That should be pretty efficient.

As @Matthew Crumley noted in a comment above, your this === " " expression will always evaluate to false. You could remove this expression, or use == if you would will be expecting a lot of strings with just a single space character:

String.prototype.isEmpty = function() {
  return this.length === 0 || this == " " || /^\s*$/.test(this);
}
Daniel Vassallo
It doesn't make sense to check if `this.length` is strictly equal to 0. Are there any valid value for `this.length` that could be equal to 0, without to be 0?
kiamlaluno
@kiamlaluno: You're right. But in general using strict equals `===` wherever possible is considered a best practice amongst many JavaScript developers. And I guess there is no harm in that.
Daniel Vassallo
Generally speaking there could be harm in using the `===` operator in at least a case.
kiamlaluno
+1  A: 
String.prototype.isEmpty = function() {
  return this.length == 0 || /^\s*$/.test(this);
}

There is just a possibility out of 255 (not considering Unicode characters with code greater than 255) that a string with length 1 contains the space character. Considering strings with lenght greater than 1, the possibility get even lower.

kiamlaluno
I'd like to challenge that probability. Why 1/255? First, you are assuming 255 characters, when in fact there are quite a bit more. Next, you assume the same probability for each character, as if you pick one at random. A space is *probably* the most common character in a block of text, and it may be very common as a single letter in the OP's scenario.
Kobi
@Kobi: I didn't speak of probability. I am not then sure the string made of just a space is the most probable string passed to a JavaScript function; if the JavaScript code is handling the username inserted from a user in a form, a string made of a single space is probably the less probable input.
kiamlaluno
What kiamlaluno is talking about is the omission of the original poster's explicit test for a string containing a single space. I agree that it is unnecessary.
Mark Thomas
@Mark Thomas: I was referring to that; thank you for clarifying what I was trying to say. `:-)`
kiamlaluno
+5  A: 

Use

String.prototype.isEmpty = function() {  
  if (!this.match(/\S/)) {
    return ('enter some valid input.Empty space is not allowed');
  } else {
   return "correct input";
  }
}


alert("test 1:"+("    ".isEmpty()));
alert("test 2:"+("   \t ".isEmpty()));
alert("test 3:"+("  \n   ".isEmpty()));
alert("test 4:"+("hi".isEmpty()));

Note:

\s will match a whitespace character: space, tab or new line.

\S will match non whitespace character:anything but not a space, tab or new line. If your string has a single character which is not a space, tab or new line, then it's not empty. Therefore you just need to search for one character: \S

Meryl
+1 good answer, and he actually doesn't need a separate function: `if(something.match(/\S/))....`
stereofrog
Sheldon Ferns.
This is not a good answer. You have not addressed performance at all. You basically came up with a worse version of my implementation (if it were corrected with Mathew Crumley's feedback). For example, does using regular expressions over checking the length of the object's property cause a performance penalty?
CantSleepAgain
A: 

I fiddled with some of the things:

  • I'm returning the inverse of this.length, for 0 that is true, for everything other number that is false.
  • I removed the check for " ". I actually haven't seen much, if any cases where a single space was entered, removing the check is IMO faster on average.
  • And flipped the regex <-> string like the others did.

String.prototype.isEmpty = function() {
return !this.length || /^\s*$/.test(this);
}

Dykam
A: 

Generally, using RegExp.prototype.test for checking for a pattern match without compilation of a return array of matches (String.prototype.match) likely has a better performance. I'd try -- but haven't tested yet -- something like:

function isEmpty() {

     var string = arguments[0] ;
     var EMPTY_STRING_PATTERN = /^\s*$/ , empty = false ;

     if( EMPTY_STRING_PATTERN.exec(string) === true ) empty = true ;

     return empty ;

}

On a side note, it is considered bad practice to fiddle with the prototype object of core javascript objects.

FK82
A: 

from example https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/String/Trim

var orig="   foo  "
document.write(orig.trim())  // foo

document.write(orig.trim().length) // 3

tested on FF 3.6.8, Safari 5.0.1, Google Chrome 5.0.375.127, but produce js error on IE 8

tsurahman