为何array.sort看似先于console.log执行?数组控制台输出异常问询
为什么调用
Array.sort()后两次console.log都显示排序后的数组? 先来看你的代码:
var queryArr = [{ns: 42, pageid: 12, lang: "en", index: 3}, {ns: 12, pageid: 36, lang: "en", index: 4}, {ns: 2, pageid: 19, lang: "en", index: 9}]; console.log(queryArr); queryArr.sort(function(i,j){ return j.index - i.index; }); console.log(queryArr);
你说两次输出都是从高到低排序的数组,其实并不是sort先于第一次console.log执行了,问题出在浏览器控制台对引用类型的显示机制上,和变量提升完全没关系~
核心原因:控制台显示的是"活"的引用
JavaScript里的数组属于引用类型,当你调用console.log(queryArr)时,控制台并不会立刻把数组的所有元素快照下来显示,而是先记录这个数组的内存引用。只有当你在控制台里点击展开这个数组的时候,它才会去读取这个引用指向的当前内存中的数组内容。
你的代码执行顺序其实完全符合预期:
- 初始化
queryArr为初始数组 - 第一次
console.log:记录数组的引用,但此时你还没展开它 - 执行
queryArr.sort():这是原地排序,直接修改了原数组的内容(没有创建新数组) - 第二次
console.log:同样记录数组的引用 - 当你后来在控制台展开这两个输出项时,数组已经被
sort修改过了,所以看到的都是排序后的结果
怎么验证真实的执行顺序?
如果你想看到执行console.log那一刻数组的真实状态,可以把数组转成字符串输出,比如用JSON.stringify:
var queryArr = [{ns: 42, pageid: 12, lang: "en", index: 3}, {ns: 12, pageid: 36, lang: "en", index: 4}, {ns: 2, pageid: 19, lang: "en", index: 9}]; console.log(JSON.stringify(queryArr)); // 这里会输出初始数组的字符串,不会被后续修改影响 queryArr.sort(function(i,j){ return j.index - i.index; }); console.log(JSON.stringify(queryArr)); // 输出排序后的数组字符串
这样就能看到第一次输出的是初始顺序,第二次是排序后的顺序了。
补充说明
这个现象是浏览器调试工具的特性,不是JS引擎的执行问题,所以Chrome和Firefox都会有同样的表现。它和变量提升无关——变量提升是指变量声明会被提升到作用域顶部,但你的代码里变量和函数的声明顺序完全没问题,执行流程也是按代码顺序走的。
内容的提问来源于stack exchange,提问作者firefiber
相关产品推荐
相关产品推荐

