【问题标题】:Chrome JavaScript developer console: Is it possible to call console.log() without a newline?Chrome JavaScript 开发者控制台:是否可以在没有换行符的情况下调用 console.log()?
【发布时间】:2012-03-26 12:36:42
【问题描述】:

我想使用console.log() 来记录消息而不 在每次调用console.log() 之后添加一个新行。这可能吗?

【问题讨论】:

  • 其中一个答案是否正确?
  • 我认为@minitech 的回答是正确的:这是不可能的。其他答案为我们对 console.log() 的理解提供了有趣的深度,如果有点正交的话。
  • @DaveLand 我相信这是perfectly possible,方法是维护您自己的显示缓冲区,并通过console.clear() 的组合将该显示缓冲区同步到实际控制台,例如console.log().
  • @JohnWeisz:谢谢,但是对于大约 99% 的应用程序来说,为每个“内联”更新擦除整个控制台并不是一个解决方案。不过,有一个 updoot。
  • @DaveLand 是的,它更像是一个 hack——现在我环顾四周,我意识到它之前已经被提出过。无论哪种方式,它有时都会很有用。

标签: javascript google-chrome console logging


【解决方案1】:

使用缓冲输出的简单解决方案。适用于 deno 并且应该适用于 node.js。 (用于将 Pascal 控制台程序移植到 javascript)

const write = (function(){
    let buffer = '';
    return function (text='\n') {
        buffer += text;
        let chunks = buffer.split('\n');
        buffer = chunks.pop();
        for (let chunk of chunks)
            {console.log(chunk);}
    }
})();

function writeln(text) { write(text + '\n'); }

要刷新缓冲区,您应该在程序结束时调用write()。 如果将此与console.log 调用混合使用,您可能会得到垃圾输出。

【讨论】:

    【解决方案2】:

    对于调试或了解长链映射实际在做什么很有用。

    let myConsole = (function(){
        let the_log_buffer=[[]], the_count=0, the_single_line=false;
        const THE_CONSOLE=console, LINE_DIVIDER='  ~  ', ONE_LINE='ONE_LINE',     
              PARAMETER_SEPARATOR= ', ', NEW_LINE = Symbol();
              
        const start = (line_type='NOT_ONE_LINE') => {
            the_log_buffer=[[]];
            the_count=0;
            the_single_line = line_type == ONE_LINE;   
            console = myConsole;  
        }
        const stop = () =>  {
            isNewline();
            console = THE_CONSOLE; 
        };                          
        const isNewline = a_param => {
            if (the_single_line && a_param==NEW_LINE) return;
            const buffer_parts = the_log_buffer.map(one_set=> one_set.join(PARAMETER_SEPARATOR))
            const buffer_line = buffer_parts.join(LINE_DIVIDER);    
            if (the_single_line) {                           
              THE_CONSOLE.clear();
            }
            THE_CONSOLE.log( buffer_line ); 
            the_log_buffer = [[]];
            the_count=0;
        }
        const anObject = an_object => {            
            if (an_object instanceof Error){
                const error_props = [...Object.getOwnPropertyNames(an_object)];
                error_props.map( error_key => an_object['_' + error_key] = an_object[error_key] );
            }
            the_log_buffer[the_count].push(JSON.stringify(an_object));
        }
        const aScalar = a_scalar => {
            if (typeof a_scalar === 'string' && !isNaN(a_scalar)) {
                the_log_buffer[the_count].push("'" + a_scalar + "'");
            } else {
                the_log_buffer[the_count].push(a_scalar);
            }
        }
        const notNewline = a_param => typeof a_param === 'object' ? anObject(a_param):aScalar(a_param);
        const checkNewline = a_param => a_param == NEW_LINE ? isNewline(a_param) : notNewline(a_param);
        const log = (...parameters_list) => {   
            the_log_buffer[the_count]=[];
            parameters_list.map( checkNewline );
            if (the_single_line){
                isNewline(undefined);
            }else{
                const last_log = parameters_list.pop();
                if (last_log !== NEW_LINE){
                    the_count++;
                }
            }
        }
        return Object.assign({}, console, {start, stop, log, ONE_LINE, NEW_LINE});
    })();
    
    function showConcatLog(){
        myConsole.stop();
        myConsole.start();
        console.log('a');
        console.log('bb');  
        console.dir({i:'not', j:'affected', k:'but not in step'})
        console.log('ccc');
        console.log([1,2,3,4,5,'6'], {x:8, y:'9'});
        console.log("dddd", 1, '2', 3, myConsole.NEW_LINE);
        console.log("z", myConsole.NEW_LINE, 8, '7');
        console.log(new Error("error test"));
        myConsole.stop();
    }
    
    myConsole.start(myConsole.ONE_LINE);
    var stop_callback = 5;
    function myCallback(){
        console.log(stop_callback, 'Date.now()', myConsole.NEW_LINE, Date.now());
        stop_callback--;
        if (stop_callback>0){
            window.setTimeout(myCallback, 1000);
        }else{
            showConcatLog();
        }
    }       
    window.setTimeout(myCallback, 1000);
    

    【讨论】:

      【解决方案3】:

      如果你想要例如控制台日志数组元素没有换行符,你可以这样做

      const arr = [1,2,3,4,5];
      
      Array.prototype.log = (sep='') => {
          let res = '';
          for(let j=0; j<this.lengthl j++){
              res += this[j];
              res += sep;
          }
          console.log(res);
      }
      
      // console loging
      
      arr.log(sep=' '); // result is: 1 2 3 4 5 
      

      【讨论】:

        【解决方案4】:

        如果您停止在多行上打印的唯一目的,一种方法是将值分组,如果您不希望它们填满整个控制台

        P.S.:-见浏览器控制台输出

        let arr = new Array(10).fill(0)
        
        
        console.groupCollapsed('index')
        
        arr.forEach((val,index) => {
          console.log(index)
        })
        
        console.groupEnd()

        console.group

        console.groupCollapsed

        【讨论】:

          【解决方案5】:

          您可以使用展开运算符在单行中显示输出。 javascript ES6 的新特性。看下面的例子

             for(let i = 1; i<=10; i++){
                  let arrData = [];
                  for(let j = 1; j<= 10; j++){
                      arrData.push(j+"X"+i+"="+(j*i));
                  }
                  console.log(...arrData);
              }
          

          这将在单行中打印 1 到 10 个表格。

          【讨论】:

            【解决方案6】:

            将您的输出收集到一个数组中,然后使用带有首选分隔符的连接函数

            function echo(name, num){
                var ar= [];
                for(var i =0;i<num;i++){
                    ar.push(name);
                }
                console.log(ar.join(', '));
            }
            
            echo("apple",3)
            

            查看Array.prototype.join() 了解模式详情

            var elements = ['Fire', 'Wind', 'Rain'];
            
            console.log(elements.join());
            // expected output: Fire,Wind,Rain
            
            console.log(elements.join(''));
            // expected output: FireWindRain
            
            console.log(elements.join('-'));
            // expected output: Fire-Wind-Rain
            

            【讨论】:

              【解决方案7】:

              在 NodeJS 中,您可以使用 process.stdout.write,如果需要,您可以添加 '\n'。

              console.log(msg) 等价于process.stdout.write(msg + '\n')

              【讨论】:

              • NodeJS 不是 Chrome。这个答案与'can you console.log without a newline?'这个问题无关紧要吗?
              • 我登陆这里是为了寻找这个,所以添加解决方案很好。其他人也这么认为。
              【解决方案8】:

              是的,这是可能的(查看下面的演示)——通过在本机浏览器控制台之上实现您自己的虚拟控制台,然后将其同步到真实控制台。

              这比听起来容易得多:

              1. 维护一个显示缓冲区(例如,一个字符串数组,每个字符串代表一行)
              2. 在写入之前调用console.clear() 以清除之前的任何内容
              3. 调用console.log()(或警告、错误等)以使用显示缓冲区中的内容填充控制台

              实际上,我已经这样做了一段时间了。这个想法的一个简短的、基本的实现将是以下几行,但仍然能够为控制台内容制作动画:

              // =================================================
              // Rudimentary implementation of a virtual console.
              // =================================================
              
              var virtualConsole = {
                  lines: [],
                  currentLine: 0,
                  log: function (msg, appendToCurrentLine) {
                      if (!appendToCurrentLine) virtualConsole.currentLine++;
                    
                      if (appendToCurrentLine && virtualConsole.lines[virtualConsole.currentLine]) {
                          virtualConsole.lines[virtualConsole.currentLine] += msg;
                      } else {
                          virtualConsole.lines[virtualConsole.currentLine] = msg;
                      }
                      
                      console.clear();
                      
                      virtualConsole.lines.forEach(function (line) {
                          console.log(line);
                      });
                  },
                  clear: function () {
                      console.clear();
                      virtualConsole.currentLine = 0;
                  }
              }
              
              // =================================================
              // Little demo to demonstrate how it looks.
              // =================================================
              
              // Write an initial console entry.
              virtualConsole.log("Loading");
              
              // Append to last line a few times.
              var loadIndicatorInterval = setInterval(function () {
                  virtualConsole.log(".", true); // <- Append.
              }, 500);
              
              // Write a new line.
              setTimeout(function () {
                  clearInterval(loadIndicatorInterval);
                  virtualConsole.log("Finished."); // <- New line.
              }, 8000);

              在与直接的控制台交互混合时,它肯定有其缺点,而且肯定看起来很丑 - 但它肯定有它的有效用途,没有它你就无法实现。

              【讨论】:

              • 这是最好的答案。您甚至可以使用保持日志堆栈足够短的 max 行数进行初始化,这样您就不会最终记录大量数据。
              【解决方案9】:

              关于@shennan 的想法:

              function init(poolSize) {
                    var pool = [];
                    console._log = console.log;
                    console.log = function log() {
                      pool.push(arguments);
                      while (pool.length > poolSize) pool.shift();
                  
                      draw();
                    }
                    console.toLast = function toLast() {
                      while (pool.length > poolSize) pool.shift();
                      var last = pool.pop() || [];
                      for (var a = 0; a < arguments.length; a++) {
                          last[last.length++] = arguments[a];
                      }
                      pool.push(last);
                  
                      draw();
                    }
                    function draw() {
                      console.clear();
                      for(var i = 0; i < pool.length; i++)
                        console._log.apply(console, pool[i]);
                    }
                  }
                  
                  function restore() {
                    console.log = console._log;
                    delete console._log;
                    delete console.toLast;
                  }
                  
                  init(3);
                  console.log(1);
                  console.log(2);
                  console.log(3);
                  console.log(4);    // 1 will disappeared here
                  console.toLast(5); // 5 will go to row with 4
                  restore();

              【讨论】:

                【解决方案10】:

                简短的回答是否定的。

                但是

                如果您的用例涉及尝试记录永久更改的数据同时避免控制台膨胀,那么实现此目的的一种方法(在某些浏览器中)是在每次输出之前使用 console.clear()

                function writeSingleLine (msg) {
                
                  console.clear();
                  console.log(msg);
                
                }
                
                writeSingleLine('this');
                setTimeout( function () { writeSingleLine('is'); }, 1000);
                setTimeout( function () { writeSingleLine('a'); }, 2000);
                setTimeout( function () { writeSingleLine('hack'); }, 3000);

                请注意,这可能会破坏您的应用程序中发生的任何其他日志记录功能。

                免责声明:我会将其归类为 hack。

                【讨论】:

                • 非常有技巧,但很聪明。如果您跟踪已经记录到控制台的内容(例如通过维护某种虚拟缓冲区),您可以重建缓冲区并在每次清除时附加一个新字符串。
                • 赞成实际回答问题!答案是否定的。
                【解决方案11】:
                // Source code for printing 2d array
                window.onload = function () {
                    var A = [[1, 2], [3, 4]];
                    Print(A);
                }
                
                function Print(A) {
                    var rows = A.length;
                    var cols = A[0].length;
                    var line = "";
                    for (var r = 0; r < rows; r++) {
                        line = "";
                        for (var c = 0; c < cols; c++) {
                            line += A[r][c] + " ";
                        }
                        console.log(line);
                    }
                }
                

                【讨论】:

                • A.forEach(row =&gt; console.log(row.join(' ')))
                【解决方案12】:

                您可以在arguments 中添加任意数量的内容:

                console.log('hi','these','words','will','be','separated','by','spaces',window,document)

                您将在一行中获得所有输出,其中包含内联对象引用,然后您可以从那里下拉他们的检查器。

                【讨论】:

                • 这如何回答这个问题?
                • 我觉得这个答案很有用。
                • 这很有用。尽管它没有回答这个问题,但它确实为大多数人在发现这个问题时会寻找什么提供了一个解决方案。
                • 任何人都想在没有换行的情况下打印的原因是以下输出未知。或者只是想象一个“加载器栏”使用例如点。
                • 使用多个参数会破坏 console.log 样式,因为您只能在第一个参数中设置样式。
                【解决方案13】:

                不,这是不可能的。如果你想把它全部放在一行中,你必须保留一个字符串并连接起来,或者把你的输出放在其他地方(比如另一个窗口)。

                【讨论】:

                • 其实是可以的,但可能不是大家心目中的用途。就我而言,我只是想打印一个问题以从命令行终端获取输入。答案见本题答案:stackoverflow.com/questions/26683734/…
                • @deltaray readline 的 question 不是 console.log。问题还在于浏览器控制台,而不是 Node.js。
                • @minitech 您可以使用扩展运算符在一行中打印。参见示例 jsfiddle.net/imranqau5373/7m65at9L/2
                • @imrankhan:这不是问题所在。与传递多个参数/使用 apply 相比,展开运算符不会在此处添加任何新内容。
                猜你喜欢
                • 1970-01-01
                • 2021-09-22
                • 2016-01-11
                • 1970-01-01
                • 2016-09-12
                • 2014-07-01
                • 2013-05-03
                • 1970-01-01
                • 2011-04-27
                相关资源
                最近更新 更多