【问题标题】:calling object properties in N levels javascript在N级javascript中调用对象属性
【发布时间】:2012-11-12 14:25:51
【问题描述】:

我正在使用 mongodb 和 ajax 调用来检索数据。当它转向 javascript 对象时,我用来生成 html 的属性有时不存在。 看看这个电话:

$.ajax({
        url: 'api/v1/mention/'+id,
        type: "GET",
        dataType: "json",
        data : {login : "demo"},
        success: function(mention) {
            display_mention_text(mention.texto);
        }
    });

在这种情况下,我调用的是mention.texto,但可以是mention.picture 或任何属性。有时它未定义并导致应用崩溃。

此方法调用对象的属性,如果未定义,则返回空字符串。 调用该方法的一些例子(第一个是对象,另一个是属性):

get_property(mention,"text")
get_property(mention,"user","name")
get_property(mention,"picture")

方法定义如下:

function get_property(obj){
    var args = Array.prototype.slice.call(arguments),
     obj = args.shift();
    if (checkNested(obj,args)) {
       //what should I do here?
    } else{
                   //the property is undefined and returns ""
        "";
    };
}


    //check if a object has N levels of propertys
function checkNested(obj /*, level1, level2, ... levelN*/) {
  var args = Array.prototype.slice.call(arguments),
      obj = args.shift();

  for (var i = 0; i < args.length; i++) {
    if (!obj.hasOwnProperty(args[i])) {
      return false;
    }
    obj = obj[args[i]];
  }
  return true;
}

在第一个方法get_property中,如果属性确实存在,我怎么称呼它?? 我会将对象和他的属性作为一个数组,例如: 对象

params = ["user","name"]

但我不能像下面这样调用:

object.["user","name"]

【问题讨论】:

  • 用来自checkNested 函数的for 循环替换get_property 函数中的if 语句。然后不返回truefalse,而是返回找到的值或""
  • 但是函数 checkNested 是返回 true 或 false,而不是值。
  • 我发布了an answer,这符合我的解释。但同样,您替换整个if 语句,并将来自另一个函数的for 语句置于其位置。然后更改返回值,这样您就不再返回truefalse

标签: javascript object


【解决方案1】:

get_property 函数中的if 语句替换为checkNested 函数中的for 循环。然后返回找到的值或"",而不是返回truefalse

function get_property(obj){
    var args = Array.prototype.slice.call(arguments),
        obj = args.shift();

     // Here's your 'for' loop. The 'if' statement is gone.
    for (var i = 0; i < args.length; i++) {
        if (!obj.hasOwnProperty(args[i])) {
          return "";   // I changed the value of this 'return' statement
        }
        obj = obj[args[i]];
    }
    return obj;  // I change the value of this 'return' statement
}

同样,我所做的只是将您自己的代码从一个函数复制粘贴到另一个函数,然后更改 return 语句的值。

【讨论】:

  • 这段代码很酷,我太专注于忘记了其他的新方法
【解决方案2】:

你可以通过这种方式实现你的目标(不需要checkNested函数):

//Parameters    {obj, prop1, prop2, ... propN}
function get_property(){
    var args = Array.prototype.slice.call(arguments),
       obj = args.shift(),
       prop = args.shift();

    if( obj.hasOwnProperty(prop) ){
        if( args.length > 0 ){
           //Calling 'get_property' with  {obj[prop1], prop2, ... propN} , and so on
           return get_property.apply(get_property, [obj[prop]].concat(args));
        }else{
           return obj[prop];
        }
    }else{
        return "";
    }
}​

用法:

var o = {
    "a" : {
        "b" : 5
    }
};

console.log( get_property(o,"c") );        //  ""
console.log( get_property(o,"a","b") );    //  5
console.log( get_property(o,"a") );        //  {"b":5}

【讨论】:

    【解决方案3】:

    您只是在寻找一个简单的递归函数。

    function get_property(obj, prop) {
        if (obj[prop]) {
            return obj[prop];
        }
        else {
            var end;
            for (var p in obj) {
                if (obj.hasOwnProperty(p)) {
                    end = get_property(obj[p], prop);
                }
            }
            if (!end) {
                // If we're there, it means there's no property in any nested level
                return;
            }
            else {
                return end;
            }
        }
    }
    

    编辑:看起来我误解了你的问题。请参阅@Engineer 的答案。保留这个答案,以防有人看起来像这样。

    【讨论】:

      【解决方案4】:

      你把事情复杂化了。如果您知道对象的树,只需调用:

      obj['user']['name'];
      

      如果您期待未定义的属性(实际上,这意味着还有其他问题):

      var prop;
      try {
          prop = obj.user.name;
      }
      catch (e) {
          prop = null;
      }
      

      【讨论】:

      • 其实在这种情况下,为了便于阅读,他最好使用obj.user.name
      • @ThiefMaster 当然,最适合他的。
      • 我知道对象的三个,但是对象用户的属性名称可能是未定义的。如果是这种情况 obj['user']['name'] 会引发异常。
      • @RodrigoDias 那么我更喜欢try/catch 表达式。它专门用来处理这个:异常。
      • 我在其他帖子中读到,针对该问题引发异常可能会使事情变得混乱。当你不需要的时候引发异常是不对的。
      猜你喜欢
      • 2011-10-29
      • 1970-01-01
      • 2020-09-12
      • 2011-11-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多