跨浏览器替换为uneval

时间:2016-10-05 09:23:59

标签: javascript serialization eval

我需要在JavaScript中编组变量,以便稍后解组。

我尝试过JSON。 JSON仅适用于number,string,boolean,null,array和object。但我想要处理的变量也可能是 RegExp 实例,或函数

我发现uneval做了我想要的事情。但它并没有任何标准,可能无法在所有浏览器上运行。

我想找到一个可以编组和解组JavaScript变量的跨浏览器解决方案。

1 个答案:

答案 0 :(得分:0)

我搜索了其他实现,但没有人适合我。所以我目前所做的是implementing another un_eval function myself ......

//希望有更好的解决方案。

var un_eval = (function () {
  var helper = function (obj, seen) {
    try {
      if (obj === null) return 'null'; // null
      if (obj === void 0) return '(void 0)'; // undefined
      if (obj == null) return '({})'; // maybe undetectable
      if (typeof obj === 'number') {
        if (1 / obj === -Infinity) return '-0';
        // toString should work all values but not -0
        return Number.prototype.toString.call(obj);
      }
      // string or boolean
      if (!(obj instanceof Object)) return JSON.stringify(obj);
      // String, Number, Boolean
      if (obj instanceof String) return '(new String(' + helper(String.prototype.valueOf.call(obj)) + '))';
      if (obj instanceof Number) return '(new Number(' + helper(Number.prototype.valueOf.call(obj)) + '))';
      if (obj instanceof Boolean) return '(new Boolean(' + helper(Boolean.prototype.valueOf.call(obj)) + '))';
      // RegExp; toString should work
      if (obj instanceof RegExp) return RegExp.prototype.toString.call(obj);
      // Date; convert obj to Number should work
      if (obj instanceof Date) return '(new Date(' + helper(Number(obj)) + '))';
      // Function
      if (obj instanceof Function) {
        var func = Function.prototype.toString.call(obj);
        if (/\{\s*\[native code\]\s*\}\s*$/.test(func)) return null;
        return '(' + func + ')';
      }
      if (seen.indexOf(obj) !== -1) return '({})';
      var newSeen = seen.concat([obj]);
      // Array
      if (obj instanceof Array) {
        var array = obj.map(function (o) { return helper(o, newSeen); });
        // Add a comma at end if last element is a hole
        var lastHole = array.length && !((array.length - 1) in array);
        return '[' + array.join(', ') + (lastHole ? ',' : '') + ']';
      }
      // Object
      if (obj instanceof Object) {
        var pairs = [];
        for (var key in obj) {
          pairs.push(JSON.stringify(key) + ':' + helper(obj[key], newSeen));
        }
        return '({' + pairs.join(', ') + '})';
      }
      return '({})';
    } catch (_ignore1) { }
    // there should be something wrong; maybe obj is a Proxy
    try {
      if (obj instanceof Object) return '({})';
      else return 'null';
    } catch (_ignore2) { }
    // there really should be something wrong which cannot be handled
    return 'null';
  };
  return function un_eval(obj) {
    return helper(obj, []);
  };
}());