最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - String conversion to undefinednullnumberboolean - Stack Overflow

programmeradmin3浏览0评论

Do you know any better and faster way to convert a string to the type it represents?

I've always been using this function:

var convertType = function (value){
    if (value === "undefined") return undefined;
    if (value === "null") return null;
    if (value === "true") return true;
    if (value === "false") return false;
    var v = Number (value);
    return isNaN (v) ? value : v;
};

Candidates:

//Me, Gabriel Llamas
var cast1 = function (value){
    if (value === "undefined") return undefined;
    if (value === "null") return null;
    if (value === "true") return true;
    if (value === "false") return false;
    var v = Number (value);
    return isNaN (v) ? value : v;
};

//KooiInc
var cast2 = function (value){
    var v = Number (value);
    return !isNaN(v) ? v : 
             value === "undefined" ? undefined
         : value === "null" ? null
         : value === "true" ? true
         : value === "false" ? false
         : value
};

//LightStyle
var cast3 = function (value){
    try {
        return (new Function("return " + value + ";"))();
    } catch(e) {
        return value;
    }
};

//Emmissary's proposal
var cast4 = function (value){
    if (value === "undefined") return undefined;
    try{
        return JSON.parse (value);
    }catch (e){
        return value;
    }
};

Benchmark code (using speedy):

var fn = function (cast){
    cast ("undefined");
    cast ("null");
    cast ("true");
    cast ("false");
    cast ("12");
    cast ("12.34");
    cast ("asd");
};

speedy.run ({
    "cast 1": function (){
        fn (cast1);
    },
    "cast 2": function (){
        fn (cast2);
    },
    "cast 3": function (){
        fn (cast3);
    },
    "cast 4": function (){
        fn (cast4);
    }
});

Result:

File: string-conversion.js

Node v0.10.18
V8 v3.14.5.9
Speedy v0.0.8

Benchmarks: 4
Timeout: 1000ms (1s 0ms)
Samples: 3
Total time per benchmark: ~3000ms (3s 0ms)
Total time: ~12000ms (12s 0ms)

Higher is better (ops/sec)

cast 1
  6,270,458 ± 0.2%
cast 2
  3,305,103 ± 0.0%
cast 3
  54,952 ± 0.0%
cast 4
  82,790 ± 0.4%

Elapsed time: 12109ms (12s 109ms)

Do you know any better and faster way to convert a string to the type it represents?

I've always been using this function:

var convertType = function (value){
    if (value === "undefined") return undefined;
    if (value === "null") return null;
    if (value === "true") return true;
    if (value === "false") return false;
    var v = Number (value);
    return isNaN (v) ? value : v;
};

Candidates:

//Me, Gabriel Llamas
var cast1 = function (value){
    if (value === "undefined") return undefined;
    if (value === "null") return null;
    if (value === "true") return true;
    if (value === "false") return false;
    var v = Number (value);
    return isNaN (v) ? value : v;
};

//KooiInc
var cast2 = function (value){
    var v = Number (value);
    return !isNaN(v) ? v : 
             value === "undefined" ? undefined
         : value === "null" ? null
         : value === "true" ? true
         : value === "false" ? false
         : value
};

//LightStyle
var cast3 = function (value){
    try {
        return (new Function("return " + value + ";"))();
    } catch(e) {
        return value;
    }
};

//Emmissary's proposal
var cast4 = function (value){
    if (value === "undefined") return undefined;
    try{
        return JSON.parse (value);
    }catch (e){
        return value;
    }
};

Benchmark code (using speedy):

var fn = function (cast){
    cast ("undefined");
    cast ("null");
    cast ("true");
    cast ("false");
    cast ("12");
    cast ("12.34");
    cast ("asd");
};

speedy.run ({
    "cast 1": function (){
        fn (cast1);
    },
    "cast 2": function (){
        fn (cast2);
    },
    "cast 3": function (){
        fn (cast3);
    },
    "cast 4": function (){
        fn (cast4);
    }
});

Result:

File: string-conversion.js

Node v0.10.18
V8 v3.14.5.9
Speedy v0.0.8

Benchmarks: 4
Timeout: 1000ms (1s 0ms)
Samples: 3
Total time per benchmark: ~3000ms (3s 0ms)
Total time: ~12000ms (12s 0ms)

Higher is better (ops/sec)

cast 1
  6,270,458 ± 0.2%
cast 2
  3,305,103 ± 0.0%
cast 3
  54,952 ± 0.0%
cast 4
  82,790 ± 0.4%

Elapsed time: 12109ms (12s 109ms)
Share Improve this question edited Sep 14, 2013 at 9:55 Gabriel Llamas asked Sep 14, 2013 at 8:07 Gabriel LlamasGabriel Llamas 18.4k26 gold badges90 silver badges117 bronze badges 8
  • 1 Other than the title of the question (the function is explicit - you aren't coercing anything), that looks fine if it does the job you require... though I would argue that it seems a little redundant and inquire as to why value isn't a primitive type to begin with? – Emissary Commented Sep 14, 2013 at 8:41
  • 1 Ok, thx for the tip. The input value is not a primitive data type because this function is typically used when parsing raw strings and you want convert a "true" or "12.34" to their types. For example, I use this function when I read a file in node.js – Gabriel Llamas Commented Sep 14, 2013 at 8:59
  • If you are parsing these values from a string with the intention of using them again in your program logic would it not be better to question the storage format? IE. surely the javascript engine's internal JSON.parse would be more efficient than any layer you can code manually? – Emissary Commented Sep 14, 2013 at 9:32
  • @Emissary I've added your proposal. Let me know if you want to modify it :) – Gabriel Llamas Commented Sep 14, 2013 at 9:44
  • that won't work because a string by itself isn't valid json - my point was that your entire input format and parsing mechanism should be substituted for those that lend themselves better to your requirements - then the cumulative time saving should include the reading and parsing too. In order to get to where you are now your input must follow some kind of pattern so that you can parse it right? Can you post an example of the input format? – Emissary Commented Sep 14, 2013 at 9:50
 |  Show 3 more comments

4 Answers 4

Reset to default 6

This is a simple function which involves the use of a function to evaluate the strings. This way you can remove the part of cases' "switch". Be aware that this handles also assignments to global variables, so I recommend it only if you know anytime where is the source from(don't allow users to use this function!)

var convertType = function (value){
    try {
        return (new Function("return " + value + ";"))();
    } catch(e) {
        return value;
    }
};

You can see the jsfiddle here.

How about:

var convertType = function (value){
  var values = {undefined: undefined, null: null, true: true, false: false}
     ,isNumber = !isNaN(+(value));
  return isNumber && +(value) || !(value in values) && value || values[value];
};
convertType('null');      //=> null
convertType('something'); //=> "something"
convertType('57.321');    //=> 57.321
convertType('undefined'); //=> undefined

This seems faster @ jsPerf

var convertType = function (value){
    var v = Number (value);
    return !isNaN(v) ? v : 
         value === "undefined" ? undefined
       : value === "null" ? null
       : value === "true" ? true
       : value === "false" ? false
       : value
 }
var string2literal = function (value){
  var maps = {
   "NaN": NaN,
   "null": null,
   "undefined": undefined,
   "Infinity": Infinity,
   "-Infinity": -Infinity
   }
  return ((value in maps) ? maps[value] : value);
};

There are many weird rules in dynamic data type converting, just map it.

The simple way of converting string to null/undefined is:

export const stringToLiteral = (value) => {
  if (value === "undefined") return undefined;
  else if (value === "null") return null;
  else return value;
};
发布评论

评论列表(0)

  1. 暂无评论