【问题标题】:Is there an equivalent for var_dump (PHP) in Javascript?Javascript 中是否有 var_dump (PHP) 的等价物?
【发布时间】:2010-09-24 07:45:45
【问题描述】:

我们需要查看一个对象在 Javascript 中有哪些方法/字段。

【问题讨论】:

标签: php javascript


【解决方案1】:

正如其他人所说,您可以使用 Firebug,这将使您对 Firefox 无后顾之忧。 Chrome 和 Safari 都有一个内置的开发者控制台,其界面与 Firebug 的控制台几乎相同,因此您的代码应该可以在这些浏览器之间移植。对于其他浏览器,有Firebug Lite

如果 Firebug 不适合您,那么试试这个简单的脚本:

function dump(obj) {
    var out = '';
    for (var i in obj) {
        out += i + ": " + obj[i] + "\n";
    }

    alert(out);

    // or, if you wanted to avoid alerts...

    var pre = document.createElement('pre');
    pre.innerHTML = out;
    document.body.appendChild(pre)
}

我建议不要提醒每个单独的属性:有些对象有很多属性,你会整天点击“OK”、“OK”、“OK”、“O...该死的我正在寻找的财产”。

【讨论】:

  • 我也建议不要这样做 - 坦率地说,我只是使用 console.debug。但我指出了循环的可能性——这取决于用户他们想对每个属性做什么
  • 我已经使用firebug有一段时间了,但不知道Firebug Lite,谢谢指出。
  • @nickf,我可以请您访问stackoverflow.com/questions/9192990/…吗? Donnow 这样的评论请求是否可以接受。
  • 我认为stackoverflow.com/a/11315561/1403755 中存在这个函数的一个稍微更健壮的版本,它本质上是 php 的 print_r 的副本
【解决方案2】:

如果您使用的是 firefox,那么firebug plug-in 控制台是检查对象的绝佳方式

console.debug(myObject);

或者,您可以像这样遍历属性(包括方法):

for (property in object) {
    // do what you want with property, object[property].value
}

【讨论】:

  • 我喜欢这种方法,因为我只需要输入几个字节。我经常使用它。
  • 这也适用于开发 react-native 应用程序 - 喜欢它!
【解决方案3】:

很多现代浏览器都支持以下语法:

JSON.stringify(myVar);

【讨论】:

  • 当接收到圆形结构而不是防范它们时会触发异常。
  • console. 选项一样,它只显示变量的内容,它不标记变量,所以如果你转储一堆变量,你必须手动标记每个变量。 :-(
【解决方案4】:

您可以为此使用console.debug(object) 是不够的。如果您以此为生,这项技术每年将为您节省数百小时:p

【讨论】:

  • 太棒了。在今天之前我从未听说过 console.debug(object) ,它为我在一个我已经苦苦挣扎了三天的表单上节省了大量时间。 20分钟后,我把它修好了。谢谢!
  • 如果它实际显示变量的名称而不只是其内容会更好,这样您就可以同时看到一堆变量而不必手动标记它们。 ¬_¬
  • @Synetech 试试console.debug({object})。如果您需要多个:console.debug({object1, object2}).
【解决方案5】:

为了从这个问题的标题的上下文中回答这个问题,这里有一个函数,它执行类似于 PHP var_dump 的操作。它每次调用只转储一个变量,但它指示数据类型和值,并且它遍历数组和对象[即使它们是对象数组,反之亦然]。我相信这可以改进。我更像是一个 PHP 人。

/**
 * Does a PHP var_dump'ish behavior.  It only dumps one variable per call.  The
 * first parameter is the variable, and the second parameter is an optional
 * name.  This can be the variable name [makes it easier to distinguish between
 * numerious calls to this function], but any string value can be passed.
 * 
 * @param mixed var_value - the variable to be dumped
 * @param string var_name - ideally the name of the variable, which will be used 
 *       to label the dump.  If this argumment is omitted, then the dump will
 *       display without a label.
 * @param boolean - annonymous third parameter. 
 *       On TRUE publishes the result to the DOM document body.
 *       On FALSE a string is returned.
 *       Default is TRUE.
 * @returns string|inserts Dom Object in the BODY element.
 */
function my_dump (var_value, var_name)
{
    // Check for a third argument and if one exists, capture it's value, else
    // default to TRUE.  When the third argument is true, this function
    // publishes the result to the document body, else, it outputs a string.
    // The third argument is intend for use by recursive calls within this
    // function, but there is no reason why it couldn't be used in other ways.
    var is_publish_to_body = typeof arguments[2] === 'undefined' ? true:arguments[2];

    // Check for a fourth argument and if one exists, add three to it and
    // use it to indent the out block by that many characters.  This argument is
    // not intended to be used by any other than the recursive call.
    var indent_by = typeof arguments[3] === 'undefined' ? 0:arguments[3]+3;

    var do_boolean = function (v)
    {
        return 'Boolean(1) '+(v?'TRUE':'FALSE');
    };

    var do_number = function(v)
    {
        var num_digits = (''+v).length;
        return 'Number('+num_digits+') '+v;
    };

    var do_string = function(v)
    {
        var num_chars = v.length;
        return 'String('+num_chars+') "'+v+'"';
    };

    var do_object = function(v)
    {
        if (v === null)
        {
            return "NULL(0)";
        }

        var out = '';
        var num_elem = 0;
        var indent = '';

        if (v instanceof Array)
        {
            num_elem = v.length;
            for (var d=0; d<indent_by; ++d)
            {
                indent += ' ';
            }
            out = "Array("+num_elem+") \n"+(indent.length === 0?'':'|'+indent+'')+"(";
            for (var i=0; i<num_elem; ++i)
            {
                out += "\n"+(indent.length === 0?'':'|'+indent)+"|   ["+i+"] = "+my_dump(v[i],'',false,indent_by);
            }
            out += "\n"+(indent.length === 0?'':'|'+indent+'')+")";
            return out;
        }
        else if (v instanceof Object)
        {
            for (var d=0; d<indent_by; ++d)
            {
                indent += ' ';
            }
            out = "Object \n"+(indent.length === 0?'':'|'+indent+'')+"(";
            for (var p in v)
            {
                out += "\n"+(indent.length === 0?'':'|'+indent)+"|   ["+p+"] = "+my_dump(v[p],'',false,indent_by);
            }
            out += "\n"+(indent.length === 0?'':'|'+indent+'')+")";
            return out;
        }
        else
        {
            return 'Unknown Object Type!';
        }
    };

    // Makes it easier, later on, to switch behaviors based on existance or
    // absence of a var_name parameter.  By converting 'undefined' to 'empty 
    // string', the length greater than zero test can be applied in all cases.
    var_name = typeof var_name === 'undefined' ? '':var_name;
    var out = '';
    var v_name = '';
    switch (typeof var_value)
    {
        case "boolean":
            v_name = var_name.length > 0 ? var_name + ' = ':''; // Turns labeling on if var_name present, else no label
            out += v_name + do_boolean(var_value);
            break;
        case "number":
            v_name = var_name.length > 0 ? var_name + ' = ':'';
            out += v_name + do_number(var_value);
            break;
        case "string":
            v_name = var_name.length > 0 ? var_name + ' = ':'';
            out += v_name + do_string(var_value);
            break;
        case "object":
            v_name = var_name.length > 0 ? var_name + ' => ':'';
            out += v_name + do_object(var_value);
            break;
        case "function":
            v_name = var_name.length > 0 ? var_name + ' = ':'';
            out += v_name + "Function";
            break;
        case "undefined":
            v_name = var_name.length > 0 ? var_name + ' = ':'';
            out += v_name + "Undefined";
            break;
        default:
            out += v_name + ' is unknown type!';
    }

    // Using indent_by to filter out recursive calls, so this only happens on the 
    // primary call [i.e. at the end of the algorithm]
    if (is_publish_to_body  &&  indent_by === 0)
    {
        var div_dump = document.getElementById('div_dump');
        if (!div_dump)
        {
            div_dump = document.createElement('div');
            div_dump.id = 'div_dump';

            var style_dump = document.getElementsByTagName("style")[0];
            if (!style_dump)
            {
                var head = document.getElementsByTagName("head")[0];
                style_dump = document.createElement("style");
                head.appendChild(style_dump);
            }
            // Thank you Tim Down [http://stackoverflow.com/users/96100/tim-down] 
            // for the following addRule function
            var addRule;
            if (typeof document.styleSheets != "undefined" && document.styleSheets) {
                addRule = function(selector, rule) {
                    var styleSheets = document.styleSheets, styleSheet;
                    if (styleSheets && styleSheets.length) {
                        styleSheet = styleSheets[styleSheets.length - 1];
                        if (styleSheet.addRule) {
                            styleSheet.addRule(selector, rule)
                        } else if (typeof styleSheet.cssText == "string") {
                            styleSheet.cssText = selector + " {" + rule + "}";
                        } else if (styleSheet.insertRule && styleSheet.cssRules) {
                            styleSheet.insertRule(selector + " {" + rule + "}", styleSheet.cssRules.length);
                        }
                    }
                };
            } else {
                addRule = function(selector, rule, el, doc) {
                    el.appendChild(doc.createTextNode(selector + " {" + rule + "}"));
                };
            }

            // Ensure the dump text will be visible under all conditions [i.e. always
            // black text against a white background].
            addRule('#div_dump', 'background-color:white', style_dump, document);
            addRule('#div_dump', 'color:black', style_dump, document);
            addRule('#div_dump', 'padding:15px', style_dump, document);

            style_dump = null;
        }

        var pre_dump = document.getElementById('pre_dump');
        if (!pre_dump)
        {
            pre_dump = document.createElement('pre');
            pre_dump.id = 'pre_dump';
            pre_dump.innerHTML = out+"\n";
            div_dump.appendChild(pre_dump);
            document.body.appendChild(div_dump);
        }  
        else
        {
            pre_dump.innerHTML += out+"\n";
        }
    }
    else
    {
        return out;
    }
}

【讨论】:

    【解决方案6】:

    您希望以 JSON 格式查看整个对象(对象的所有嵌套级别和其中的变量)。 JSON 代表 JavaScript Object Notation,打印出对象的 JSON 字符串相当于 var_dump(获取 JavaScript 对象的字符串表示)。幸运的是,JSON 在代码中非常容易使用,而且 JSON 数据格式也非常易于人类阅读。

    例子:

    var objectInStringFormat = JSON.stringify(someObject);
    alert(objectInStringFormat);
    

    【讨论】:

      【解决方案7】:

      console.dir(朝向链接页面的底部)在 firebug 或 google-chrome web-inspector 中将输出对象属性的交互式列表。

      另见this Stack-O answer

      【讨论】:

      • 太糟糕了,它实际上并没有给它贴上标签;它仅显示其值,如果您想查看一堆变量,则无济于事。 :-|
      【解决方案8】:

      如果您使用 Firebug,您可以使用 console.log 输出对象并在控制台中获取超链接、可探索的项目。

      【讨论】:

      • 这样做的问题是它没有标记变量,所以如果你转储一堆变量,你必须手动标记它们以区分它们。 :-\
      【解决方案9】:

      对于不知道传入变量类型的人来说,对nickf的功能进行了一点改进:

      function dump(v) {
          switch (typeof v) {
              case "object":
                  for (var i in v) {
                      console.log(i+":"+v[i]);
                  }
                  break;
              default: //number, string, boolean, null, undefined 
                  console.log(typeof v+":"+v);
                  break;
          }
      }
      

      【讨论】:

        【解决方案10】:

        我改进了 nickf 的答案,所以它递归循环对象:

        function var_dump(obj, element)
        {
            var logMsg = objToString(obj, 0);
            if (element) // set innerHTML to logMsg
            {
                var pre = document.createElement('pre');
                pre.innerHTML = logMsg;
                element.innerHTML = '';
                element.appendChild(pre);
            }
            else // write logMsg to the console
            {
                console.log(logMsg);
            }
        }
        
        function objToString(obj, level)
        {
            var out = '';
            for (var i in obj)
            {
                for (loop = level; loop > 0; loop--)
                {
                    out += "    ";
                }
                if (obj[i] instanceof Object)
                {
                    out += i + " (Object):\n";
                    out += objToString(obj[i], level + 1);
                }
                else
                {
                    out += i + ": " + obj[i] + "\n";
                }
            }
            return out;
        }
        

        【讨论】:

          【解决方案11】:
          console.log(OBJECT|ARRAY|STRING|...);
          console.info(OBJECT|ARRAY|STRING|...);
          console.debug(OBJECT|ARRAY|STRING|...);
          console.warn(OBJECT|ARRAY|STRING|...);
          console.assert(Condition, 'Message if false');
          

          这些应该可以在 Google Chrome 和 Mozilla Firefox 上正常运行(如果您使用的是旧版本的 firefox,那么您必须安装 Firebug 插件)
          在 Internet Explorer 8 或更高版本上,您必须执行以下操作:

          • 通过单击 F12 按钮启动“开发者工具”
          • 在选项卡列表中,单击“脚本”选项卡
          • 点击右侧的“控制台”按钮

          欲了解更多信息,您可以访问此网址:https://developer.chrome.com/devtools/docs/console-api

          【讨论】:

            【解决方案12】:

            你可以简单地使用 NPM 包 var_dump

            npm install var_dump --save-dev
            

            用法:

            const var_dump = require('var_dump')
            
            var variable = {
              'data': {
                'users': {
                  'id': 12,
                  'friends': [{
                    'id': 1,
                    'name': 'John Doe'
                  }]
                }
              }
            }
            
            // print the variable using var_dump
            var_dump(variable)
            

            这将打印:

            object(1) {
                ["data"] => object(1) {
                    ["users"] => object(2) {
                        ["id"] => number(12)
                        ["friends"] => array(1) {
                            [0] => object(2) {
                                ["id"] => number(1)
                                ["name"] => string(8) "John Doe"
                            }
                        }
                    }
                }
            }
            

            链接:https://www.npmjs.com/package/@smartankur4u/vardump

            稍后谢谢!

            【讨论】:

              【解决方案13】:

              如果你正在寻找用 JS 转换的 PHP 函数,有这个小站点:http://phpjs.org。 在那里,您可以获得大部分用 JS 可靠编写的 PHP 函数。对于 var_dump 试试:http://phpjs.org/functions/var_dump/(一定要查看置顶评论,这取决于“echo”,也可以从同一个站点下载)

              【讨论】:

                【解决方案14】:

                我使用了第一个答案,但我觉得其中缺少递归。

                结果是这样的:

                function dump(obj) {
                    var out = '';
                    for (var i in obj) {
                        if(typeof obj[i] === 'object'){
                            dump(obj[i]);
                        }else{
                            out += i + ": " + obj[i] + "\n";
                        }
                    }
                
                    var pre = document.createElement('pre');
                    pre.innerHTML = out;
                    document.body.appendChild(pre);
                }
                

                【讨论】:

                  【解决方案15】:

                  基于这篇文章中以前的函数。 添加了递归模式和缩进。

                  function dump(v, s) {
                    s = s || 1;
                    var t = '';
                    switch (typeof v) {
                      case "object":
                        t += "\n";
                        for (var i in v) {
                          t += Array(s).join(" ")+i+": ";
                          t += dump(v[i], s+3);
                        }
                        break;
                      default: //number, string, boolean, null, undefined 
                        t += v+" ("+typeof v+")\n";
                        break;
                    }
                    return t;
                  }
                  

                  例子

                  var a = {
                    b: 1,
                    c: {
                      d:1,
                      e:2,
                      d:3,
                      c: {
                        d:1,
                        e:2,
                        d:3
                      }
                    }
                  };
                  
                  var d = dump(a);
                  console.log(d);
                  document.getElementById("#dump").innerHTML = "<pre>" + d + "</pre>";
                  

                  结果

                  b: 1 (number)
                  c: 
                     d: 3 (number)
                     e: 2 (number)
                     c: 
                        d: 3 (number)
                        e: 2 (number)
                  

                  【讨论】:

                  • 这很好,但最好显示变量的名称(就像在 PHP 中一样),这样您就可以区分多个变量而无需手动标记它们。
                  【解决方案16】:

                  这是我的解决方案。它很好地复制了var_dump 的行为,并允许嵌套对象/数组。请注意,它不支持多个参数。

                  function var_dump(variable) {
                    let out = "";
                    
                    let type = typeof variable;
                    if(type == "object") {
                      var realType;
                      var length;
                      if(variable instanceof Array) {
                        realType = "array";
                        length = variable.length;
                      } else {
                        realType = "object";
                        length = Object.keys(variable).length;
                      }
                      out = `${realType}(${length}) {`;
                        for (const [key, value] of Object.entries(variable)) {
                      out += `\n [${key}]=>\n ${var_dump(value).replace(/\n/g, "\n  ")}\n`;
                    }
                    out += "}";
                    } else if(type == "string") {
                      out = `${type}(${type.length}) "${variable}"`;
                    } else {
                      out = `${type}(${variable.toString()})`;
                    }
                    return out;
                  }
                  console.log(var_dump(1.5));
                  console.log(var_dump("Hello!"));
                  console.log(var_dump([]));
                  console.log(var_dump([1,2,3,[1,2]]));
                  
                  console.log(var_dump({"a":"b"}));

                  【讨论】:

                    【解决方案17】:

                    游戏晚了,但这里有一个非常方便的函数,使用起来超级简单,允许您传递任意类型的任意数量的参数,并且将在浏览器控制台窗口中显示对象内容,就像您从 JavaScript 调用 console.log - 但从 PHP 调用

                    注意,您也可以通过传递 'TAG-YourTag' 来使用标签,它将一直应用到读取另一个标签,例如,'TAG-YourNextTag'

                    /*
                    *   Brief:          Print to console.log() from PHP
                    *   Description:    Print as many strings,arrays, objects, and other data types to console.log from PHP.
                    *                   To use, just call consoleLog($data1, $data2, ... $dataN) and each dataI will be sent to console.log - note that
                    *                   you can pass as many data as you want an this will still work.
                    *
                    *                   This is very powerful as it shows the entire contents of objects and arrays that can be read inside of the browser console log.
                    *                   
                    *                   A tag can be set by passing a string that has the prefix TAG- as one of the arguments. Everytime a string with the TAG- prefix is
                    *                   detected, the tag is updated. This allows you to pass a tag that is applied to all data until it reaches another tag, which can then
                    *                   be applied to all data after it.
                    *
                    *                   Example:
                    *                   consoleLog('TAG-FirstTag',$data,$data2,'TAG-SecTag,$data3); 
                    *                   Result:
                    *                       FirstTag '...data...'
                    *                       FirstTag '...data2...'
                    *                       SecTag   '...data3...' 
                    */
                    function consoleLog(){
                        if(func_num_args() == 0){
                            return;
                        }
                    
                        $tag = '';
                        for ($i = 0; $i < func_num_args(); $i++) {
                            $arg = func_get_arg($i);
                            if(!empty($arg)){       
                                if(is_string($arg)&& strtolower(substr($arg,0,4)) === 'tag-'){
                                    $tag = substr($arg,4);
                                }else{      
                                    $arg = json_encode($arg, JSON_HEX_TAG | JSON_HEX_AMP );
                                    echo "<script>console.log('".$tag." ".$arg."');</script>";
                                }       
                            }
                        }
                    }
                    

                    注意:func_num_args()func_num_args() 是 php 函数,用于读取动态数量的输入 args,并允许此函数有无限多个 console.log 请求来自一个函数调用

                    【讨论】:

                      【解决方案18】:

                      以下是我最喜欢的 var_dump/print_r 等效 Javascript 到 PHP var_dump

                      function dump(arr,level) {
                          var dumped_text = "";
                          if(!level) level = 0;
                          
                          //The padding given at the beginning of the line.
                          var level_padding = "";
                          for(var j=0;j<level+1;j++) level_padding += "    ";
                          
                          if(typeof(arr) == 'object') { //Array/Hashes/Objects 
                              for(var item in arr) {
                              var value = arr[item];
                                  if(typeof(value) == 'object') { //If it is an array,
                                      dumped_text += level_padding + "'" + item + "' ...\n";
                                      dumped_text += dump(value,level+1);
                                  } else {
                                      dumped_text += level_padding + "'" + item + "' => \"" + value + "\"\n";
                                  }
                              }
                          } else { //Stings/Chars/Numbers etc.
                              dumped_text = "===>"+arr+"<===("+typeof(arr)+")";
                          }
                          return dumped_text;
                      }
                      

                      【讨论】:

                        【解决方案19】:

                        我只是想补充一些关于console.log比较重要的东西

                        如果您正在调试大型变量(如大型音频或视频数据缓冲区)。当您打印 console.log(big_variable) 时,控制台只会显示其中的一小部分。 (似乎有点明显)。

                        但是,如果变量处于循环中并且该变量不断变化,如果您曾经“将其复制到剪贴板”,浏览器会再次请求变量(这可能已被复制时间)。

                        我会告诉你我的故事。我正在编写一个处理大量音频数据的应用程序,其 Float32arrays 大小为 8192。如果缓冲区具有某些特征,我将使用 console.log() 打印该变量,然后抓取该变量进行测试和玩弄用它(甚至用它来模拟,这样我就可以进行自动化测试)

                        但是,结果永远不会成立。麦克风将捕获音频数据,将其存储在 this.audioBuffer 变量中,整个过程都可以正常工作,但是当我从 console.log 复制该变量时,我可以将其作为模拟运行一些自动化测试,行为会发生巨大变化。

                        我花了一段时间才弄清楚这一点,显然,每当我在调试器中“复制”或“将变量设置为全局”时,而不是复制显示在 console.log 中的变量,jsvm 会要求这个.audioBuffer 再次。由于变量是在循环内使用的,麦克风仍然会记录,我会得到一个完全不同的声音阵列,而不是我正在听的声音,并认为音频缓冲区是第一位的。

                        如果您正在处理大型复杂数据结构,例如音频或视频文件、图像文件......并且当您读取 chrome /firefox / edge 控制台中的值时,这些数据结构可能会发生变化,请确保您没有console.log(variable),而是 console.log(JSON.stringify(variable))。这将为您节省大量时间

                        【讨论】:

                          猜你喜欢
                          • 2010-09-23
                          • 1970-01-01
                          • 2011-08-05
                          • 1970-01-01
                          • 2012-11-17
                          • 1970-01-01
                          • 2010-09-27
                          • 1970-01-01
                          • 1970-01-01
                          相关资源
                          最近更新 更多