2017-10-20 49 views
3

我有一個從服務器端JavaScript,發送作爲字符串返回的對象,我嘗試恢復,如:如何刪除功能)匿名(S在JavaScript

/* function that determines whether or not a String should be a function (namely, if it is the string form of a function) 
* Parameters: 
* • str : the string to check 
* Returns: 
* • true if str should be a function, or false otherwise 
* NOTE: the primary use for this function is for restoring stringified member functions of objects returned from the server 
*/ 
function shouldBeFunction(str) 
{ 
    str = str.toString().trim(); 
    // str should *not* be function iff it doesn't start with 'function' 
    if (str.indexOf('function') !== 0) return false; 
    // str should *not* be function iff it doesn't have a '(' and a ')' 
    if ((str.indexOf('(') === -1) || (str.indexOf(')') === -1)) return false; 
    // str should *not* be function iff it doesn't have a '{' and a '}' 
    if ((str.indexOf('{') === -1) || (str.indexOf('}') === -1)) return false; 
    return true; 
} 

/* reviver function for stringified objects that contain stringified methods 
* Parameters : 
* • key : the key of the object 
* • value : the value of object[key] 
*/ 
function objectReviver(key, value) 
{ 
    var DEBUG = false; 
    if ((typeof(value) === 'string') && (shouldBeFunction(value))) { 
     if (DEBUG) { 
      console.log('function string detected on property named : ' + key); 
      console.log('function text: " ' + value + '"'); 
     } 
     // get arguments list, if there is one to get 
     var argsList = value.substring(value.indexOf('(') + 1, value.indexOf(')')).trim(); 
     if (DEBUG) console.log('argsList == ' + argsList); 
     var functionBody = value.substring(value.indexOf('{') + 1, value.lastIndexOf('}')).trim(); 
     if (DEBUG) console.log('functionBody == ' + functionBody); 
     if (argsList) 
      return new Function(argsList, functionBody);  
     return new Function(functionBody); 
    } 
    return value; 
} 

var myObj = JSON.parse(objStringFromServer, objectReviver); 

然而,當我檢查它的所有方法時,它們看起來都是匿名函數,這些函數稍後會在我的代碼中導致問題! (即,我有一個Map<Object, String>,它似乎深入比較了get()中指定的Object與地圖中的任何鍵,包括其toString()方法。)我該如何解決這個問題?

+0

是否有可能有一個與聲明,並在同一行重新調整的問題嗎?請參閱https://stackoverflow.com/questions/19145476/javascript-define-and-return-a-variable-on-one-line類似的,但與變量而不是功能。 – Paul

回答

1

發現這個靈感在另一篇文章:Is there any non-eval way to create a function with a runtime-determined name?

/* function that determines whether or not a String should be a function (namely, if it is the string form of a function) 
 
* Parameters: 
 
* • str : the string to check 
 
* Returns: 
 
* • true if str should be a function, or false otherwise 
 
* NOTE: the primary use for this function is for restoring stringified member functions of objects returned from the server 
 
*/ 
 
function shouldBeFunction(str) 
 
{ 
 
    str = str.toString().trim(); 
 
    // str should *not* be function iff it doesn't start with 'function' 
 
    if (str.indexOf('function') !== 0) return false; 
 
    // str should *not* be function iff it doesn't have a '(' and a ')' 
 
    if ((str.indexOf('(') === -1) || (str.indexOf(')') === -1)) return false; 
 
    // str should *not* be function iff it doesn't have a '{' and a '}' 
 
    if ((str.indexOf('{') === -1) || (str.indexOf('}') === -1)) return false; 
 
    return true; 
 
} 
 

 
/* reviver function for stringified objects that contain stringified methods 
 
* Parameters : 
 
* • key : the key of the object 
 
* • value : the value of object[key] 
 
*/ 
 
function objectReviver(key, value) 
 
{ 
 
    var DEBUG = false; 
 
    var argList = ""; 
 
    if ((typeof(value) === 'string') && (shouldBeFunction(value))) { 
 
     if (DEBUG) { 
 
      console.log('function string detected on property named : ' + key); 
 
      console.log('function text: " ' + value + '"'); 
 
     } 
 
     // get arguments list, if there is one to get 
 
     var argsList = value.substring(value.indexOf('(') + 1, value.indexOf(')')).trim(); 
 
     if (DEBUG) console.log('argsList == ' + argsList); 
 
     var functionBody = value.substring(value.indexOf('{') + 1, value.lastIndexOf('}')).trim(); 
 
     if (DEBUG) console.log('functionBody == ' + functionBody); 
 
     var f = new Function(
 
      "return function " + key + "() {\n" + 
 
      functionBody + 
 
      "};" 
 
     )(); 
 
     return f; 
 
    } 
 
    return value; 
 
} 
 

 
var myObj = JSON.parse('{"test":"function(){alert(1);}"}', objectReviver); 
 
console.log(myObj.test);