Passing an empty string literal to a function

Just a quick one. Just noticed that when trying to pass an empty string literal “” to a function that it’s converted to null.

I want to use that argument as a context to execute a callback on. e.g. arg = fn.call(arg, xxx);

The only way around it was to pass a new String(‘’) object instead, however I see on JSHint that you get reprimanded for using the string constructor.

Any other way around this?

Cheers

RLM

Something strange is going on then, for with the following code I see in my console different results, depending on if it’s an empty string or null


function show(obj) {
    console.log(obj);
}

> show("");

<-undefined
> show(null);
null
<-undefined

What in your situation causes it to be changed from an empty string to null?

You’re right. It seemed strange. A flaw elsewhere in my code perhaps.

function check(x){
  console.log(x);
  console.log({}.toString.call(x));
};

check("");

-->(an empty string)
-->[object String]

What in your situation causes it to be changed from an empty string to null?

It’s in my css parser a call to parentLookUp. Will give it another look.

That would be this one here:


parentLookUp = function (child, fn, obj) {
  if (obj) {
    while (child = child.parent) {
      obj = fn.call(obj, child);
    }
    return obj;
  } else {
    while (child = child.parent) fn(child);
  }
},

What types of expected arguments are you wanting to use with that., Can you provide some examples that both include and exclude the empty string?

Paul it needs work.

I wanted the function to have some flexibility, so that if down the line if I want to pass an array to it I can. Needs thinking out.

Just knocked up a simplified example of usage

function func(fn, obj){
  
  return fn.apply(obj);

}

function prefix () { return this.replace(/^/, 'Starts here...'); }

console.log(func(prefix, ""));

In parentLookUp ‘Start here’ would be a value supplied by a child property.

An example of the code calling the function is.

parentLookUp(cssRule, function (child) {
			  return (child.selector) ? this.replace(/^/, child.selector + ' ') : this;
             }, "" );

Alternate usage is just a simple lookup so that a function can gain access to those properties. No object supplied. As in the parseVars function I use to replace variables with their values.

Spotted the flaw. ‘if (obj)’

Will never be true for on an empty string

However with the new String wrapper.


var x = "";

if(x) console.log('false');
>

var x = new String('');

if(x) console.log('true');

> true

Need to sort out my type checking.

Something like this.

if (obj !== undefined || obj !== null)

Okay, so what are you wanting to check instead? Just that if something is passed as the third parameter?


if (obj !== undefined) {
    ...
}

That will let defined objects be used, even if they are an empty string too.

if (obj !== undefined)

Yes that’s it. Sometimes can’t see the wood for the trees.

Cheers

RLM