为什么对console.log的javascript调用会影响逻辑流?

时间:2015-09-04 19:54:02

标签: javascript prototype console.log

在Javascript中,我使用console.log进行调试。看起来,一旦我解决了逻辑,我就可以自信地取出调试语句而不会影响逻辑。这是相反的证据。 (暂时说,因为我可能错了!)首先,程序;请查找长系列的星号。 (我自己会看一本教科书;这是一本作业,但是你没有帮我做作业。我正在努力理解这门语言!)

            void Main()
            {

                var psi = new ProcessStartInfo("cmd.exe", "/c notepad");
                var cmdProcess = Process.Start(psi);
                Thread.Sleep(2000);
                KillProcessAndChildren(cmdProcess.Id);

            }

            public void KillProcessAndChildren(int pid)
            {
            using (var searcher = new ManagementObjectSearcher
                ("Select * From Win32_Process Where ParentProcessID=" + pid))
            {
                var moc = searcher.Get();
                foreach (ManagementObject mo in moc)
                {
                    KillProcessAndChildren(Convert.ToInt32(mo["ProcessID"]));
                }
                try
                {
                    var proc = Process.GetProcessById(pid);
                    proc.Kill();
                }
                catch (Exception e)
                {
                    // Process already exited.
                }
            }
            }

该代码的输出是:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Why is call to console.log needed?</title>
    <script type="text/javascript">
        /** IterAbstract: Constructor for a means of visiting every object in
         * a collection.
         *
         * @param arr: the collection, either an ArraySeq or a RangeSeq
         * @returns
         *   method getNext returns (1) (most likely) a member of arr;
         *     possibly the value undefined, if that's in the collection, or
         *     (2) the value undefined, an tentative indication that there
         *     are no further elements.
         *   method getAtEnd returns (1) true, if no further elements remain,
         *     or (2) false, if further elements remain to be sent.
         * @constructor IterAbstract
         * Users should use only the two methods.
         */
        function IterAbstract (arr) {
            this.arr = arr;
            this.last = this.arr.length - 1;
            this.lastSent = null;
            this.atEnd = false;
        }
            /* *************************
               The focus is the call to console.log at the start of the
               function following these comments.
               ************************* */
            /* The expected behavior of this file is that when function
               logFive receives a two-element array, there will be three calls
               to getNext. The first call uses the return commented "return
               for the first element"; it returns the first element of the
               array and logFive puts it on console.log. The second call uses
               the return commented "return for all other elements"; that
               return makes all other elements available for logFive to record
               on console.log. The third call creates the unambiguous "we're
               past the end of file" signal (a combination of this.atEnd=true
               and returning the undefined value); it uses the return
               commented "after-the-end return".

               When logFive gets an array [1, 2], we expect to see two calls
               to console.log, one with each element.

               When logFive gets an array [null, undefined], we expect the same,
               though with different (and admittedly squirrely) elements
               demonstrated.

               Good: When the subject call to console.log occurs (not commented
               out), the expected behavior occurs. Though there are interspersed
               lines starting "getNext", we see rows with the four expected
               outputs: 1, 2, null, and undefined.

               Bad: When we comment out the subject call to console.log, we see
               three of the four expected rows: 1, 2, and null.

               There is a series of three other calls to console.log designed
               to show us which exit the code uses. They have been commented out
               before; let's uncomment the them.

               Good: Though there are interspersed lines starting "getNext", we
               see the four expected rows. The code is using the expected
               returns.

               Why do these debugging calls to console.log affect actual logic
               flow? (he he) Where's the user error here?
            */
        IterAbstract.prototype.getNext = function () {
            console.log("getNext   this.lastSent=" + this.lastSent +
                    "   this.atEnd=" + this.atEnd);
            if (this.lastSent === this.last) {
                //console.log("getNext after-the-end return   this.lastSent="+
                //        this.lastSent+"   this.last="+this.last);
                this.atEnd = true;
                return undefined; // after-the-end return
            }
            if (this.lastSent === null) {
                this.lastSent = 0;
                //console.log("getNext first exit   element=0");
                return this.arr[0]; // return for the first element
            }
            var sent=this.lastSent+1;
            //console.log("getNext normal exit   element="+sent);
            return this.arr[++this.lastSent]; // return for all other elements
        };
        IterAbstract.prototype.getAtEnd = function () { return this.atEnd; };
        /** logFive: Shows the first five elements of a collection on
         * console.log; less, if the collection has less.
         * @param arr: the collection, either an ArraySeq or a RangeSeq
         */
        function logFive (arr) {
            var iterArr = new IterAbstract(arr);
            /*console.log("after Constructor   iterArr.arr="+iterArr.arr+
                    "   iterArr.last="+iterArr.last+
                    "   iterArr.lastSent="+iterArr.lastSent+
                    "   iterArr.atEnd="+iterArr.atEnd); */
            var response;
            for (i=0; i < 5; i++) {
                //console.log("start iter   i="+i+
                //        "   iterArr.atEnd="+iterArr.atEnd);
                response = iterArr.getNext();
                /*console.log("iter i="+i+"   response="+response+
                        "   iterArr.atEnd="+iterArr.atEnd);*/
                if (response === undefined && iterArr.getAtEnd()) return;
                //console.log("iter normal exit");
                console.log(response);
        }   }
        function ArraySeq ( arr ) {
            return arr;
        }
        console.log ("logFive(new ArraySeq([1, 2]));");
        logFive(new ArraySeq([1, 2]));
        // → 1
        // → 2
        console.log ("logFive(new ArraySeq([null,undefined]);");
        logFive(new ArraySeq([null,undefined]));
        // → null
        // → undefined
    </script>
</head>
<body>
<p>Output for this program goes to console.log.</p>

<p>In Firefox, press Ctrl-Shift-K to see that output.</p>

<p>In Chrome, press Ctrl-Shift-J to see that output.</p>
</body>
</html>

甜!几乎完成了。这就是我想要的,除了以“getNext”开头的行。让我们在getNext的开头注释掉对console.log的调用。然后,输出变为:

logFive(new ArraySeq([1, 2]));
getNext   this.lastSent=null   this.atEnd=false 
1 
getNext   this.lastSent=0   this.atEnd=false 
2 
getNext   this.lastSent=1   this.atEnd=false 
logFive(new ArraySeq([null,undefined]); 
getNext   this.lastSent=null   this.atEnd=false 
null 
getNext   this.lastSent=0   this.atEnd=false 
undefined 
getNext   this.lastSent=1   this.atEnd=false

喂!不公平。 我需要另一条线,“未定义”。它去哪儿了?

也许如果我能弄清楚每次使用什么返回语句,我会学到一些有趣的东西。我将在getNext中的每个出口点取消注释对console.log的三次调用。现在,输出变为:

logFive(new ArraySeq([1, 2])); 
1 
2 
logFive(new ArraySeq([null,undefined]); 
null

叹息。如果我可以将调试语句放入,我可以得到正确的输出,除了额外的垃圾。

日wassup?提前谢谢!

1 个答案:

答案 0 :(得分:2)

Firefox将null和undefined组合在一起。在它们之间放置另一个console.log会强制它们不再按分组。当显示多个类似的日志时,分组可以帮助保持控制台更清洁,例如在循环中。

这里Firefox将所有内容记录在一个单独的行上,因为没有背靠背的行类似: enter image description here

但由于某种原因,它认为null和undefined类似,足以在它们背靠背时组合在一起:

enter image description here

您的输出是正确的。 Firefox显示它的方式不是。