为啥console.log 显示的数组与alert 不同?

Posted

技术标签:

【中文标题】为啥console.log 显示的数组与alert 不同?【英文标题】:Why does console.log display array different than alert?为什么console.log 显示的数组与alert 不同? 【发布时间】:2022-01-19 16:23:56 【问题描述】:

我写了一个以特定方式过滤对象的函数(按键分组,但只有连续的,它工作正常)。

groupBySequentialValues(array, key) 
    let groupName = null;
    let groupIndex = 0;
    let result = []; // keep this in mind!

    array.forEach((el, index) => 
        if (groupName !== array[index][key]) 
            groupName = array[index][key]
            groupIndex++;
            result[groupIndex + '_' + groupName] = []
        
        result[groupIndex + '_' + groupName].push(el);
    )

    alert(result);
    console.log(result);

起初警报显示一个空数组,但警报关闭后,控制台日志将显示正确组装的数组。 (当然,这也是在没有警报的情况下发生的,这只是最好地显示了差异) 但是我不能在警报或模板中使用这个数组(我在 VueJS 中使用它来呈现一个列表,但就像我说的那样它是空的)。 开发工具似乎看到了它的内容,但警报/dom没有。 在将结果数组声明为对象( 而不是[])后,它起作用了。 为什么开发工具/控制台日志会以这种方式运行?它是一个调试工具,但是当它像这样运行时,我不能依赖它作为调试工具..

【问题讨论】:

What is a Property Accessor 您可能正在向它推送一个对象,但它仍然是一个没有数组索引的数组? 是这个---> result[groupIndex + '_' + groupName] javascript 中的数组只是一个具有特殊能力的对象,例如是iterable 并继承Array.prototype。因此,您可以像使用对象一样在其上声明任何新属性。这正是你正在做的事情。 @Randy Casburn 我知道我的代码有什么问题。请阅读整个问题:) 【参考方案1】:

JavaScript Array 当然是一个数组,但它也是一个对象。

而且,它接受索引作为字符串没有问题:

const a = [1, 2, 3]
console.log(a[0])
console.log(a['0'])

那些console.log会输出数组的第一个值=1。

因此该数组具有广泛的容错性,这就是为什么应该小心使用它以避免以非常难以调试的错误形式出现意外。

在您的情况下,您应该使用对象或地图。

更新

还要考虑到 window.alert 与 console.log 有很大的不同。

window.alert 尝试打印输入的字符串格式,应该作为字符串传递,但如果不是,则强制执行。

这意味着:

const x = 
alert(x)

将打印 [object Object]。 而如果你使用:

console.log(x)

你会看到:


而且你将能够浏览对象的方法和属性,即使对象是空的。

【讨论】:

那么即使将结果声明为数组,我的代码也应该可以工作,但事实并非如此。恐怕你没有回答我的问题。 如果你将字符串作为数组的索引,它就可以工作。 好吧,我的情况不是这样。它仅在使用控制台记录输出时有效。我不能在警报中使用它。 警报函数的签名与console.log 完全不同。当 console.log 打印出对象时,alert 不会,而是打印字符串表示形式。【参考方案2】:

在构造对象并将该对象打印到控制台时,console.log() 将输出对象自身的属性及其值。如果您使用对象的.toString() 方法console.log() 对象,您将在控制台中收到[object Object]。这是您在对象的警报中看到的确切结果:

const obj = ;
obj['test'] = 'this is a test';
console.log(obj);
console.log(obj.toString());
alert(obj);

如果您创建一个数组并且console.log() 其内部的toString() 方法会打印数组的元素,并用[] 包围它们。当alert()一个数组时,.toString()方法用于只打印数组值:

let arr = [1,2,3];
console.log(arr);
alert(arr);

最后,您的代码向数组对象添加属性,而不是向数组添加元素。发生这种情况时,console.log() 会像第一个示例一样打印此对象,但因为这是一个数组对象,所以它将[] 放置在属性及其值周围,而不是。由于数组是(没有元素),它会按字面意思打印[]

下面的代码演示了您的代码创建的数组对象的结构,显示数组元素的数量为零,显示数组对象的属性名称,显示与该属性关联的值,最后在控制台中显示对象。

如果您按照前面示例中的说明提醒result,则对话框将为空,因为数组中没有元素。

let groupName = 'test';
let groupIndex = 0;
let el = 'this is a test';
let result = [];

result[groupIndex + '_' + groupName] = []
result[groupIndex + '_' + groupName].push(el);

console.log('Number of elements in result array: ', result.length);
console.log('result Object Property Names: ', Object.getOwnPropertyNames(result));
console.log('result Object Property Value: ', result[Object.getOwnPropertyNames(result)[1]]);

console.log(result);

【讨论】:

你是第一个真正理解并回答我问题的人!谢谢你。在我的项目中,控制台日志不像你的那样工作,我的输出完整的数组,而不是一个空的...... 每个平台都不一样。例如,在我的 WebStorm IDE 的控制台中,我可以看到您所描述的内容,但在 Safari 中,我看到了我所描述的内容。 此外,在本网站的 StackSnippets 中,控制台已经过清理,其行为也与其他一些平台有所不同。 如果您发现它回答了您的问题,请考虑接受我的回答。谢谢。 我会的!但这意味着最终 console.log 确实是一个用于调试/测试目的的糟糕工具。 (虽然是最常见的/基本的)

以上是关于为啥console.log 显示的数组与alert 不同?的主要内容,如果未能解决你的问题,请参考以下文章

为啥console.log() 被认为比alert() 更好?

为啥“return”与“console.log()”不一样[重复]

简介alert()与console.log()的不同

JavaScript中的alert()与console.log()的区别

console.log()与console.dir()

javascript console.log 一个包含数组元素的对象时,输出的对象是修改后的,代码和输入如下