传递一个对象's的层次结构作为它的参数'的父函数

Passing an object's hierarchy as an argument to it's parent function

本文关键字:参数 函数 一个对象 层次结构      更新时间:2023-09-26

我在一个名为tpl()的函数中有一个称为html的对象。

html = {
    intro: ['intro', 'html'],
    common: { header: ['common', 'header', 'html'] },
    more:{ header: { link: ['hello', 'world'] } }
};

我试图通过将html的层次结构作为参数传递给tpl()来访问它的值;

我传递一个字符串common.header作为参数,以便返回内部对象的内容。

[示例]:

var a = tpl('common.header'); // correct, returns 'common header html'

问题是,当我需要针对更深层次的嵌套对象时:

var b = tpl('more.header.link'); // how can i make this work ?

这是我写的函数,但我正在努力使其更加动态(使其能够处理更深层次的对象)。

var tpl = function( path ){
  if(!path){ return false; }
  var that = this;
  that.html = {
    intro: ['intro', 'html'],
    common: { header: ['common', 'header', 'html'] },
    more: { header: { link: ['hello', 'world'] } }
  };
  path = path.split('.');
  return (!!path[1] ? that.html[path[0]][path[1]] : that.html[path[0]]).join('');
  /*
  // Here is where I am stuck
  for(var i = 0; i < path.length; i++){
    if( path[i][ path[i+1] ] ){}
  }
  */
};

如果我正确理解你的问题,那么保留一个指向当前子结构的指针怎么样?像这样:

for(var tmp = that.html, i = 0; i < path.length; i++){
    tmp = tmp[path[i]];
    if (!tmp) return false;
}
return tmp;

试试这个

var tpl = function( path ){
    if(!path){ return false; }
    var that = this;
    that.html = {
        intro: ['intro', 'html'],
        common: { header: ['common', 'header', 'html'],
                  footer: { text2: 'text2' } },
        more:{ header: { link: ['hello', 'world'] } }
    };
    path = path.split('.');
    var val = that.html;
    for(var i = 0; i < path.length; i++){
        val = val[path[i]];
    }
    return val;
};

演示

这是一个很难回答的问题,因为我不知道你未来对这个函数的想法是什么。目前,在我看来,你似乎真的过于复杂了从对象中提取数据的方法。例如,

var tpl = function( path ){
    if(!path){ return false; }
    var that = this;
    that.html = {
        intro: ['intro', 'html'],
        common: { header: ['common', 'header', 'html'] },
        more:{ header: { link: ['hello', 'world'] } }
    };
    return eval("that.html."+path);
};

console.log( tpl("common.header") );

参考:http://jsfiddle.net/8z4mC/

这将做我认为你想要的,然而,当你考虑时,这段代码的工作方式完全相同

html = {
    intro: ['intro', 'html'],
    common: { header: ['common', 'header', 'html'] },
    more:{ header: { link: ['hello', 'world'] } }
};

console.log( html.common.header );

参考:http://jsfiddle.net/jPLD5/

也许你需要解释一下未来的目的,以便有人做出更好的回答?

我喜欢@ori的解决方案。这里有另一个递归选项:

function resolvePath(object, path){
    if (!path || !path.length || path[0] === "") {
        return object;
    } else if (typeof path === 'string'){
        path = path.split('.');
    }
    var pathComponent = path.shift();
    if (pathComponent in object){
        return resolvePath(object[pathComponent], path);
    } else {
        throw new Error("Key does not exist.");
    }
}