views:

55

answers:

3

While looking at adding a trim function to the String prototype, I came across something that seems odd to me with JavaScript strings.

if (typeof console === 'undefined') {
    var console = { };
    console.log = function(msg) {
        alert(msg)
    }
}


function isString(str) {
    return ((str && typeof str === 'string') || 
        (str && (str.constructor == String && (str.toString() !== 'null' && str.toString() !== 'undefined'))));
}

if (!String.prototype.trim) {
    String.prototype.trim = function () {
        return this.replace(/^\s*(\S*(?:\s+\S+)*)\s*$/, "$1");
    };
}
function testing (str) {
    if (isString(str)) {
        console.log("Trimmed: " + str.trim() + " Length: " + str.trim().length);
    } else {
        console.log("Type of: " + typeof str);
    }
    return false;
}

function testSuite() {
    testing(undefined);
    testing(null);
    testing("\t\r\n");
    testing("   90909090");
    testing("lkkljlkjlkj     ");
    testing("    12345       ");
    testing("lkjfsdaljkdfsalkjdfs");
    testing(new String(undefined));                //Why does this create a string with value 'undefined'
    testing(new String(null));                     //Why does this create a string with value 'null'
    testing(new String("\t\r\n"));
    testing(new String("   90909090"));
    testing(new String("lkkljlkjlkj     "));
    testing(new String("    12345       "));
    testing(new String("lkjfsdaljkdfsalkjdfs"));
}

Now I know that we shouldn't be creating Strings with the new operator, but I'd hate to have someone call this on an undefined or null string that was created more along the lines of:

    new String ( someUndefinedOrNullVar );

What am I missing? Or is the !== 'null' && !== 'undefined' check really necessary (Removing that check, will show 'null' and 'undefined')?

A: 

I believe new String(null) and new String(undefined) return the value types which are strings: 'null' and 'undefined'.

Edit: Actually, null is an object. But I think I'm right about undefined.

Silkster
+4  A: 

From the ECMA standard:

9.8 ToString
The abstract operation ToString converts its argument to a value of type String according to Table 13 
[ the table shows undefined converts to "undefined" and null to "null"]

...and then:

15.5.2.1 new String ( [ value ] )
The [[Prototype]] internal property of the newly constructed object is set to the standard built-in String prototype object that is the initial value of String.prototype (15.5.3.1).
The [[Class]] internal property of the newly constructed object is set to "String".
The [[Extensible]] internal property of the newly constructed object is set to true.
The [[PrimitiveValue]] internal property of the newly constructed object is set to ToString(value), or to the empty String if value is not supplied.

So since ToString(undefined) gives 'undefined', it makes sense.

jrtipton
A: 

All objects in JavaScript can be cast to a string value, which is exactly what new String(null) does. The !== 'null' && !== 'undefined' check in this case is extreme foolproofing, although... the following all result in a string.

'' + null // 'null'
'' + undefined // 'undefined'
[null].join() // 'null'

But still imo. the extra foolproving is needless for trim(), heck, maybe someone actually has a string 'null' or 'undefined' or if not, would be great to see so you can debug it. Nay, remove the check!

BGerrissen