10

I was following a tutorial that suggested to check if an object is string and not empty as the following:

var s = "text here";
if ( s && s.charAt && s.charAt(0))

it is said that if s is string then it has a method charAt and then the last component will check if the string is empty or not.

I tried to test it with the other available methods like ( typeof and instanceof ) using some of the SO questions and here and here too !!

so I decided to test it in Js Bin : jsbin code here as follow:

var string1 = "text here";
var string2 = "";


alert("string1  is " + typeof string1);
alert("string2  is " + typeof string2);


//part1- this will succeed and show it is string
if(string1 && string1.charAt){
  alert( "part1- string1 is string");
}else{
  alert("part1- string1 is not string ");
}


//part2- this will show that it is not string
if(string2 && string2.charAt ){
  alert( "part2- string2 is string");
}else{
  alert("part2- string2 is not string ");
}



//part3 a - this also fails !!
if(string2 instanceof String){  
  alert("part3a- string2 is really a string");
}else{
  alert("part3a- failed instanceof check !!");
}

//part3 b- this also fails !!
//i tested to write the String with small 's' => string
// but then no alert will excute !!
if(string2 instanceof string){  
  alert("part3b- string2 is really a string");
}else{
  alert("part3b- failed instanceof check !!");
}

Now my questions are :

1- why does the check for string fails when the string is empty using the string2.charAt ???

2- why does the instanceof check failed??

9
  • if(string2.charAt) is only checking if method is defined, an empty string is still a string so will return true Commented Jul 19, 2014 at 19:21
  • @charlietfl plz refere to answer of adeneo where he said "A simple string is not an object, it's a primary data type, and has no prototype, as opposed to a String object created with new String." Commented Jul 19, 2014 at 20:34
  • So empty string defind as literal will not return true if checked for the charAt function presence Commented Jul 19, 2014 at 20:36
  • @stackunderflow It would, if using the code provided. (Because "".charAt(0) -> "" -> false-y. The thing that would not work is "" instanceof String && .., because it is a string value, not a String object. Commented Jul 19, 2014 at 20:36
  • 1
    @stackunderflow following your logic you could never do 'somestring'.charAt(n) Commented Jul 19, 2014 at 21:21

2 Answers 2

14

string values are not String objects (which is why the instanceof fails)2.

To cover both cases using "type-checking" it would be typeof x === "string" || x instanceof String; the first only matches strings and the latter matches Strings.

The tutorial assumes that [only] String objects - or string values which are promoted1 - have a charAt method and so uses "duck-typing". If the method does exist, then it is called. If charAt is used out-of-bounds then an empty string "", which is a false-y value, is returned.

The tutorial code would also accept a string of "\0", while s && s.length would not - but it would also "work" on arrays (or jQuery objects, etc). Personally, I trust the caller to provide the allowed values/types and use as little "type-checking" or special-casing as possible.


1 For primitive values of string, number, and boolean there is a corresponding object type of String, Number, and Boolean, respectively. When x.property is used on one of these primitive values the effect is ToObject(x).property - hence the "promotion". This is discussed in ES5: 9.9 - ToObject.

Neither the null or undefined values have corresponding objects (or methods). Functions are already objects but have a historically different, and useful, typeof result.

2 See ES5: 8 - Types for the different types of values. The String Type, eg., represents a string value.

Sign up to request clarification or add additional context in comments.

Comments

7

1- Why does the check for string fails when the string is empty using the string2.charAt?

The following expression evaluates to false because the first condition fails:

var string2 = "";
if (string2 && string2.charAt) { console.log("doesn't output"); }

That second line is basically equivalent to:

if (false && true) { console.log("doesn't output"); }

So for example:

if (string2) { console.log("this doesn't output since string2 == false"); }
if (string2.charAt) { console.log('this outputs'); }

2- Why does the instanceof check fail?

This fails because, in javascript, string can be literals or objects. For example:

var myString = new String("asdf");
myString instanceof String; // true

However:

var myLiteralString = "asdf";
myLiteralString instanceof String; // false

You can reliably tell if it's a string by checking both the type and the instanceof:

str instanceof String || typeof str === "string";

1 Comment

you missed something . my question was not putting parameter zero . it is actually without brackets. if(string1 && string1.charAt){

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.