2
\$\begingroup\$

I need to convert a string value to its primitive type in JavaScript. Other values that are not of type String should just be returned.

Example:

  1. String '34' should be converted to 34

  2. String '34px' should be kept as '34px'

  3. true should return true

  4. 'true' should return true

Here is a working example (please look at console).

I would like to know:

  • If there is any better way to write the same function, in term of performance.
  • If I missed some type or any other issues.

function convert(value) {
    var result = value;
    if (typeof value === 'string') {
        // check if it is a empty character
        value.trim();
        if (value.length > 0) {
            if (/\S/.test(value)) {
                if (value === 'true') {
                    result = true;
                } else if (value === 'false') {
                    result = false
                } else if (!isNaN(value)) {
                    result = new Number(value);
                }
            }
        }
    }
    return result;
}
\$\endgroup\$

1 Answer 1

2
\$\begingroup\$

On thing to keep in mind is that certain inputs that you might not consider to be numbers will be considered numbers by the isNaN and Number functions.

Potentially Unexpected Numbers:

  • Infinity ("Infinity")
  • hexidecimal notation ("0x1a3")
  • scientific notation ("0e9" and "0e+9" and "0e-9")

function convert(value) {
    var result = value;
    if (typeof value === 'string') {
        // check if it is a empty character
        value.trim();
        if (value.length > 0) {
            if (/\S/.test(value)) {
                if (value === 'true') {
                    result = true;
                } else if (value === 'false') {
                    result = false
                } else if (!isNaN(value)) {
                    result = new Number(value);
                }
            }
        }
    }
    return result;
}

var rows = document.querySelectorAll(".row");
for(var i = 0; i < rows.length; i++){
  var input = rows[i].querySelector(".in");
  var output = rows[i].querySelector(".out");
  var type = rows[i].querySelector(".type")
  
  var value = input.getAttribute("value");
  if(value){input.innerHTML = "\""+value+"\""}
  
  var result = convert(input.getAttribute("value"));
  output.innerHTML = result
  
  var typeValue = typeof result === "object" ? isNaN(result) ? typeof result : result === null ? "null" : "number" : typeof result;
  type.innerHTML = typeValue;
  if(typeValue === "number"){if(type.classList){type.classList.add("highlight");}else{type.className = type.className + " " + "highlight";}}
}
.table{display:table;border-left:1px solid black;table-layout:fixed; min-width:300px;}
.headerRow{display:table-row;background-color:#dfdfdf;font-weight:bold;}
.headerCell{display:table-cell; border-right:1px solid black; border-bottom:1px solid black; border-top:1px solid black;}
.row{display:table-row;}
.cell{display:table-cell; border-right:1px solid black;border-bottom:1px solid #dfdfdf;}
.highlight{background-color:lightgreen;}
<div class="table">
  <div class="headerRow">
    <div class="headerCell">Input String</div>
    <div class="headerCell">Output Value</div>
    <div class="headerCell">Output Type</div>
  </div>
  <div class="row">
    <div class="in cell"></div>
    <div class="out cell"></div>
    <div class="type cell"></div>
  </div>
  <div class="row">
    <div class="in cell" value=" 9e99 "></div>
    <div class="out cell"></div>
    <div class="type cell"></div>
  </div>
  <div class="row">
    <div class="in cell" value="Infinity"></div>
    <div class="out cell"></div>
    <div class="type cell"></div>
  </div>
  <div class="row">
    <div class="in cell" value="">""</div>
    <div class="out cell"></div>
    <div class="type cell"></div>
  </div>
  <div class="row">
    <div class="in cell" value="0x9"></div>
    <div class="out cell"></div>
    <div class="type cell"></div>
  </div>
  <div class="row">
    <div class="in cell" value="0x1A9"></div>
    <div class="out cell"></div>
    <div class="type cell"></div>
  </div>
  <div class="row">
    <div class="in cell" value="099.90"></div>
    <div class="out cell"></div>
    <div class="type cell"></div>
  </div>
  <div class="row">
   <div class="in cell" value="1e8"></div>
   <div class="out cell"></div>
    <div class="type cell"></div>
  </div>
  <div class="row">
   <div class="in cell" value="true"></div>
   <div class="out cell"></div>
    <div class="type cell"></div>
  </div>
  <div class="row">
   <div class="in cell" value="TRUE"></div>
   <div class="out cell"></div>
    <div class="type cell"></div>
  </div>
  <div class="row">
   <div class="in cell" value="12px"></div>
   <div class="out cell"></div>
    <div class="type cell"></div>
  </div>
  <div class="row">
   <div class="in cell" value="false"></div>
   <div class="out cell"></div>
    <div class="type cell"></div>
  </div>
</div>

Boolean values are also considered numbers, but your function has that covered.

\$\endgroup\$
2
  • \$\begingroup\$ Many thanks for your explanation, do you have any idea how to improve the code in order to support these cases? Thanks \$\endgroup\$
    – GibboK
    Mar 13, 2015 at 14:59
  • \$\begingroup\$ There are multiple ways to handle those cases, but the important thing is to be sure you understand how your method is expected to behave in each case. You could use JavaScript's isFinite() method to handle "Infinity". To detect exponents and scientific notation so you can treat them differently from numbers, you could check for the characters "e" or "x" in the inputs, either via regex or string.indexOf(). \$\endgroup\$
    – Thriggle
    Mar 13, 2015 at 15:58

Your Answer

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

Not the answer you're looking for? Browse other questions tagged or ask your own question.