console.log如何工作?

时间:2011-08-18 17:32:35

标签: javascript console logging

第一个例子:

在以下示例中:http://jsfiddle.net/maniator/ScTAW/4/
我有这个js:

var storage = (function () {
    var store = [];
    return {
        "add": function (item) {
            store.push(item);
        },
        "get": function () {
            return store;
        }
    };
}());

storage.add('hi there')
console.log(storage, storage.get(), storage.add('hi there #2'));

以下是打印到控制台的内容:

  

对象    [“hi there”,“hi there#2”] undefined

有人会认为控制台应该只说:

  

对象    [“hi there”] undefined

因为第二次推送在记录值之后才发生,因此不应显示。


第二个例子:

在以下示例中:http://jsfiddle.net/maniator/ScTAW/5/

我正在使用相同的storage变量,但我记录如下:

storage.add('hi there')
console.log(storage, storage.get(), (function() {
    storage.add('hi there #2');
    console.log('TESTING');
})());

打印到控制台的内容是:

  

TESTING
  宾语    [“hi there”,“hi there#2”] undefined

嗯,这很奇怪现在不是吗?人们可以期待看到:

  

对象    [“hi there”] undefined
  测试

为什么会这样?控制台日志记录机制幕后发生了什么?

4 个答案:

答案 0 :(得分:18)

在大多数(如果不是全部)命令式编程语言中,必须在调用函数之前评估传递给函数调用的任何参数(所谓的Eager evaluation)。此外,它们通常按从左到右的顺序进行评估(对于C,例如它未定义),但是在两个示例中,参数的计算顺序无关紧要。在查看详细情况时,这应该是非常明显的:

如前所述,在调用console.log之前,必须先执行storage.get(),然后返回store数组。然后storage.add('hi there #2')将被执行(或反过来),因此其结果(在这种情况下为undefined,因为add不返回任何内容)可以作为第三个参数传递给{ {1}}。这意味着将使用参数console.log调用一次console.log(storage, storage.store, undefined)数组已经包含“hi there#2”,从而产生您观察到的结果。

在第二个例子中,推理再次相同,函数调用稍微模糊一些。首先看它看起来有一个函数作为第3个参数传递给store函数;但它实际上是一个函数调用(观察者最后是console.log)。因此()将被执行,然后storage.add('hi there #2'),然后匿名函数执行的console.log('TESTING')结果将再次传递给undefined

如果您确实将函数传递给console.log,它将打印该函数定义,而不执行任何操作。所以:

console.log

,最后没有storage.add('hi there') console.log(storage, storage.get(), (function() { storage.add('hi there #2'); console.log('TESTING'); })); ,结果为:

()

我希望这会让事情变得更加清晰。

答案 1 :(得分:2)

当你像这样打电话给console.log

console.log(storage, storage.get(), storage.add('hi there #2'));
评估

storage.add('hi there #2'),并将 返回值 传递给console.log。评估它会导致数组项立即添加到store

storage.get()相同的事情 - > store。如此有效,声明变为:

console.log(storage, store, [return value of add which is undefined]);

打印时,会评估store并输出其内容,这就是您看到["hi there", "hi there #2"]

的原因

在第二个例子中,首先评估匿名函数并传递结果。

答案 2 :(得分:1)

console.log的所有参数将首先被迭代和评估,以便汇编输出。在迭代您传递的参数时,会对对象进行更改并调用函数。 后,记录器迭代了参数,输出数据。

因为对象是byRef,所以storage.store对象的“第二个参数”更改会反映在控制台输出中。因为参数是迭代的,所以最后一个参数中的函数调用在输出汇编之前被称为,所以在看到第一个console.log的输出之前,你会看到函数调用的输出。调用

值得注意的是,console.log的输出不会显示调用console.log时存在的对象。在对象的情况下,实际获得的是对象的引用句柄。因此,在将句柄添加到console.log的输出后对对象所做的任何更改仍将反映在对象本身中。由于句柄仅指向对象本身,因此您不会获得显示对象状态的输出,就像调用函数时一样,而是显示对象的实时链接,因为它现在是

答案 3 :(得分:1)

console.log 被称为之前,完全评估了存储添加功能,因为它是一个参数。

这不是console.log特有的,这就是每种命令式编程语言的工作方式。