Javascript深度搜索和对象更改 [英] Javascript deep search and change in object

查看:34
本文介绍了Javascript深度搜索和对象更改的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个JavaScript函数,它在对象上进行挖掘并为函数对象创建一个字符串值. 拥有以下JSON:

I have a JavaScript function what is dig through on object and make a string value to function object. Have this JSON:

{
  "active": true,
  "icons": {
     "activeHeader": "ui-icon-alert"
  },
  "animate": {
     "duration": 1000, "always": "dMethod"
  }
}

我在此字符串上使用JSON.parse,所以我以string的形式到达options.animate.always,其值为dMethdod,这实际上是方法的名称.因此,我可以通过window[options.animate.always]进行访问,并且希望将options.animate.always从字符串更改为指向该字符串的方法. 我为此工作准备了一个函数:

I use JSON.parse on this string so I reach options.animate.always as a string with value dMethdod which is actually a name of the method. So I can access this through window[options.animate.always] and I wish to change the options.animate.always from string to method that is pointed to the string. I make a function for this job:

function SetFunctions(options, functionName) {
  var path = functionName.split(".");
  var setterObject = options;
  for (var k = 0; k < path.length; k++) {
    if (setterObject != undefined) {
      setterObject = setterObject[path[k]];
    } else {
      break;
    }
  }
  if (setterObject != undefined && window[setterObject] != undefined) {
    setterObject = window[setterObject];
  }
}

我使用从解析返回的变量和函数名称animate.always作为值来调用此函数. 找到正确属性的部分可以工作,但是当我设置setterObject的值时,更改不会影响原始值.
我正在考虑将引用建立为字符串'options.animate.always = dMethod'并在其上使用eval,但是我真的想避免使用eval函数(我知道eval是邪恶的:)).

I call this function with the variable returned from the parse and function name animate.always as value. The part that find the correct property is worked, but when I set the value of the setterObject the change is not affect the original value.
I'm thinking to build up the reference as string 'options.animate.always = dMethod' and use eval on it, but I really want to avoid using eval function (I know eval is evil :)).

最终解决方案:
我把答案放在一起,完成了我的方法.终于成为两种方法.我对此发表评论并分享给其他人也许有用:

FINAL SOULUTION:
I put answers together and finished my method. Finally become two methods. I comment it and share maybe useful to others:

function ChangeStringToFunction(functionPath, rootObject, separator) {
  // functionPath is required parameter
  if (functionPath === undefined || functionPath === null) return;
  // rootObject is optional. If not supplied the window object will be the base of the search
  var localRootObject = rootObject === undefined ? window : rootObject;
  // separator is optional. If not supplied the '.' will be the separator
  var localSeparator = separator === undefined ? "." : separator;
  // split the string reference (example "jui.someObj1.someOjb2"
  var pathParts = functionPath.split(localSeparator);
  var currentObject = localRootObject;
  // exclude the last part
  for (var i = 0; i < pathParts.length - 1; i++) {
    currentObject = currentObject[pathParts[i]];
    // it's useless to go forward if there is no object
    if (currentObject === undefined) return;
  }
  // get the string represent the name of the function (full path could be included)
  var currentValue = currentObject[pathParts[pathParts.length - 1]];
  // the value must be a string
  if (typeof currentValue !== "string") return;

  // get the function reference based on the value provided
  var functionReference = ResolveFunction(currentValue);
  // if the result is not a function it's meaningless to continue
  if (typeof functionReference !== "function") return;

  // and finally change the string value of the object with the function value represent by our string
  currentObject[pathParts[pathParts.length - 1]] = functionReference;
}

function ResolveFunction(functionPath, separator, rootObject) {
  if (functionPath === undefined || functionPath === null) return undefined;
  var localRootObject = rootObject === undefined ? window : rootObject;
  var localSeparator = separator === undefined ? "." : separator;
  var pathParts = functionPath.split(localSeparator);
  var currentObject = localRootObject;
  for (var i = 0; i < pathParts.length; i++) {
    currentObject = currentObject[pathParts[i]];
    if (currentObject === undefined) break;
  }

  return typeof currentObject === "function" ? currentObject : undefined;
}

推荐答案

但是当我设置setterObject的值时,更改不会影响原始值.

but when I set the value of the setterObject the change is not affect the original value.

是的,您仅分配给变量.因为变量没有指针,所以除了变量之外,它将永远不会改变任何其他东西.

Yes, you are only assigning to a variable. That will never change anything else but the variable, since JavaScript does not have pointers.

要更改对象,必须将其分配给属性.对于您的情况,您将不得不省略最后一次迭代来获取对象,然后将其分配给:

To change an object, you will have to assign to a property. In your case, you will have to omit the last iteration to get the object which you then assign to:

function SetFunctions(options, functionName) {
    var path = functionName.split("."),
        setterObject = options;
    for (var k=0; setterObject!=null && k<path.length-1; k++) {
        setterObject = setterObject[path[k]];
    }
    var prop = path[k],
        fn = setterObject!=null && window[setterObject[prop]];
    if (fn) {
        setterObject[prop] = fn;
    }
}

顺便说一句,我认为在您的情况下构建CallFunctions函数以存储在该属性中的名称直接调用该函数可能会更容易,而不是用方法替换该属性值-除非您打算非常频繁地调用它.

Btw, I think in your case it might be easier to build a CallFunctions function that directly invokes the function with the name stored in that property, instead of replacing the property value with the method - unless you plan to invoke it very often.

这篇关于Javascript深度搜索和对象更改的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆