将对象的层次结构作为参数传递给它的父函数

时间:2012-01-31 15:40:10

标签: javascript jquery

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

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

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

我传递一个String 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] ] ){}
  }
  */

};

4 个答案:

答案 0 :(得分:4)

如果我正确理解你的问题,如何保持指向当前子结构的指针?像这样:

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

答案 1 :(得分:3)

试试这个

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;
};

<强> Demo

答案 2 :(得分:1)

这是一个难以回答的问题,因为我不知道你对这个功能的未来想法是什么。目前它看起来好像你实际上是在复杂化从对象中提取数据的方法。例如,

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/

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

答案 3 :(得分:1)

我喜欢@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.");
    }
}