最近作死又去做了一遍javascript-puzzlers上的44道变态题,这些题号称“JS语言专业八级”的水准,建议可以去试试,这里我不去解析这44道题了,网上已经有很多的答案了。我只介绍让我意想不到的几种特殊情况下的数组操作方法结果。关于数组原生方法的基本操作我在另一篇博客里已经做了简介:吃透Javascript数组操作的正确姿势—再读《Js高程》.....下面的输出结果,未做特殊说明是在Node环境中运行的结果。

第一题:

What is the result of this expression? (or multiple ones)

[ [3,2,1].reduce(Math.pow), [].reduce(Math.pow) ]

an error[9, 0][9, NaN][9, undefined]

Per spec: reduce on an empty array without an initial value throws TypeError

在Node环境中可以自行执行上面的表达式,结果会产生TypeError: Reduce of empty array with no initial value

也就是说在不能在空数组上调用不带初始参数的reduce方法,可以像下面这样调用,增加一个初始参数

1
console.log([ [3,2,1].reduce(Math.pow), [].reduce(Math.pow,1)])//输出[9,1]

第二题:

What is the result of this expression? (or multiple ones)

var ary = [0,1,2];ary[10] = 10;ary.filter(function(x) { return x === undefined;});

[undefined × 7][0, 1, 2, 10][][undefined]

Array.prototype.filter is not invoked for the missing elements.

由上面的结果可以得知,“稀疏数组”中丢失的元素并不会唤起filter方法的调用,但是如果你打印出稀疏元素

1
console.log(ary[5]);//undefined

结果确实是undefined。打印整个数组看一下:

1
console.log(ary)//[ 0, 1, 2, , , undefined, , , , , 10 ]

所以这种通过直接给ary[10]赋值的方式产生的数组并不将未赋值的地方变成真正的undefined。

创建“稀疏数组”的方法也不只这一种,那么其他方法会不会也是这种情况呢。

1
2
3
4
var ary = [0,1,2];
ary.length = 10;
console.log(ary)//[ 0, 1, 2, , , , , , ,  ]
console.log(ary.filter(function(x) { return x === undefined;})); //[]

从上例可以看到使用设置arr.length的方法创建的稀疏数组也是一样的情况。

1
2
3
4
5
6
var ary = Array(10);
ary[0]=0;
ary[1]=1;
ary[2]=2;
console.log(ary)//[ 0, 1, 2, , , , , , ,  ]
console.log(ary.filter(function(x) { return x === undefined;})); //[]



从上可以看出通过ary = Array(10);创建的稀疏数组同样出现这样情况。



接下来拓展一下,直接将undefined赋值给ary[5]

1
2
3
4
5
var ary = [0,1,2];
ary[5]=undefined;//直接将undefined赋值给ary[5]
ary[10] = 10;
console.log(ary)//[ 0, 1, 2, , , undefined, , , , , 10 ]
console.log(ary.filter(function(x) { return x === undefined;})); //[ undefined ]

从结果中可以看出只有ary[5]通过了筛选。
稀疏数组的这种特性在数组的map方法中是否存在呢,接着看第三题。

第三题:

What is the result of this expression? (or multiple ones)

var ary = Array(3);ary[0]=2;ary.map(function(elem) { return '1'; });

[2, 1, 1]["1", "1", "1"][2, "1", "1"]other The result is ["1", undefined × 2], as map is only invoked for elements of the Array which have been initialized.

官网给出了上面的 解析,在浏览器中运行就是上面的结果,我在Node环境中显示的结果是[ '1', ,  ]。不管怎么样都说明了在稀疏元素上并没有唤起调用map的回调函数。

2016-7-20补充:那么有没有办法让稀疏数组唤起调用map或者上一题的filter方法呢?看完下面的例子大概就清楚了

1
2
3
4
5
var a = Array(10).join(",").split(",").map(function(item, index) {
  return index;
});
 
console.log(a);

通过join方法把它转成字符串,然后,再通过split方法把字符串转成数组,这时候,它就拥有10个值为空的元素了,然后,再通过map函数,改变这些元素的值即可。




第四题: 

What is the result of this expression? (or multiple ones)

var x = [].reverse;x();

[]undefinederrorwindow

[].reverse will return this and when invoked without an explicit receiver object it will default to the default this AKA window



reverse 方法颠倒数组中元素的位置,并返回该数组的引用。出题者的意图是该方法会返回this,然后在全局环境中这个this就是window,而实际上经过我测试,在谷歌浏览器上显示错误:

     Uncaught TypeError: Array.prototype.reverse called on null or undefined(…)

在Node环境中显示
TypeError: Array.prototype.reverse called on null or undefined

 可以看出实际上 var x = [].reverse返回的是对数组reverse方法的引用,直接调用的话会出错。可以使用call方法调用

1
2
3
4
var x = [].reverse;
var arr=[1,2,3];
 
console.log( x.call(arr)); //[ 3, 2, 1 ]




 第五题:

What is the result of this expression? (or multiple ones)

[,,,].join(", ")





JavaScript allows a trailing comma when defining arrays, so that turns out to be an array of three undefined.

因为javascript 在定义数组的时候允许最后一个元素后跟一个,, 所以这是个长度为三的稀疏数组(这是长度为三, 并没有 0, 1, 2三个属性哦),同理


1
2
var arr=Array(3);
console.log(arr.join(", ") )//, ,

 

参考:



javascript-puzzlers

44个 Javascript 变态题解析 (上)

44个 Javascript 变态题解析 (下)



再探JS数组原生方法—没想到你是这样的数组的更多相关文章

  1. JS 中 原生方法 (二) --- 数组 (修---添加ES6新增)

    const arr = [1, 2, 3, 5, 'a', 'b'] /** * * length * 这个只能被 称之为 数组的原生属性, 返回 一个 number * arr.length */ ...

  2. JS 中 原生方法 (四) --- Object

    Javascript 中 str. arr.date.obj 等常见的原生方法总结 本文也说主要阐释了 Javascript 中的基础类型和 引用类型的自带方法,那么熟悉的同学又可以绕道了 总是绕道, ...

  3. JS 中 原生方法 (三) --- Date 日期

    本文也说主要阐释了 Javascript 中的基础类型和 引用类型的自带方法,那么熟悉的同学又可以绕道了 总是绕道,真是羞耻悳boy 当然 本文阐述的主要类容 from MDN ( zh-cn ) D ...

  4. JS 中 原生方法 (一) --- 字符串

    目录 Javascript 中 str. arr.date.obj 等常见的原生方法总结 Javascript 中 str. arr.date.obj 等常见的原生方法总结 本文也说主要阐释了 Jav ...

  5. N皇后求解。万万没想到,只用一个一维数组就搞定了。还体现了回溯。

    一.啥是N皇后?先从四皇后入手 给定一个4x4的棋盘,要在棋盘上放置4个皇后.他们的位置有这样的要求,每一列,每一行,每一对角线都能有一个皇后. 你可能会对这个对角线有疑惑,其实就是每一个小正方形的对 ...

  6. 浅谈Vue响应式(数组变异方法)

    很多初使用Vue的同学会发现,在改变数组的值的时候,值确实是改变了,但是视图却无动于衷,果然是因为数组太高冷了吗? 查看官方文档才发现,不是女神太高冷,而是你没用对方法. 看来想让女神自己动,关键得用 ...

  7. 原生Js 两种方法实现页面关键字高亮显示

    原生Js 两种方法实现页面关键字高亮显示 上网看了看别人写的,不是兼容问题就是代码繁琐,自己琢磨了一下用两种方法都可以实现,各有利弊. 方法一 依靠正则表达式修改 1.获取obj的html2.统一替换 ...

  8. 原生JS中apply()方法的一个值得注意的用法

    今天在学习vue.js的render时,遇到需要重复构造多个同类型对象的问题,在这里发现原生JS中apply()方法的一个特殊的用法: var ary = Array.apply(null, { &q ...

  9. 再谈React.js实现原生js拖拽效果

    前几天写的那个拖拽,自己留下的疑问...这次在热心博友的提示下又修正了一些小小的bug,也加了拖拽的边缘检测部分...就再聊聊拖拽吧 一.不要直接操作dom元素 react中使用了虚拟dom的概念,目 ...

随机推荐

  1. linux awk命令详解

    linux awk命令详解 简介 awk是一个强大的文本分析工具,相对于grep的查找,sed的编辑,awk在其对数据分析并生成报告时,显得尤为强大.简单来说awk就是把文件逐行的读入,以空格为默认分 ...

  2. MVC防止xss攻击 ——Html.AntiForgeryToken的AJAX提交

    1.在Html表单里面使用了@Html.AntiForgeryToken()就可以阻止CSRF攻击. 2.相应的我们要在Controller中也要加入[ValidateAntiForgeryToken ...

  3. js 查找树节点 数组去重

    //查找树节点function findData(curOrg, id) { var array = []; if ((typeof curOrg == 'object') && (c ...

  4. MyBatis传入多个参数的问题

    一.单个参数: public List<XXBean> getXXBeanList(String xxCode); <select id="getXXXBeanList&q ...

  5. 使用Cocos2d-x实现微信“天天爱消除”炫耀button特效

    引言Cocos2d-x引擎中有很多Action,这样可以方便的让开发者调用相应的Action去完成一些动作,例如:移动,弹跳,淡入淡出等.可在实际的开发过程中,由于游戏的需要,显然地,引擎自带的Act ...

  6. SQL Server性能计数器部署(批量)

    一.计数器部署项目介绍 SQL Server每个服务器,日常需要监控的计数器指标高达上百,若一个个手动添加非常麻烦.此项目通过命令行工具针对指定计数器集成部署,提高部署效率.此包括开发数据库互联(OD ...

  7. Qt 5.0+ 中 connect 新语法与重载函数不兼容问题的解决方法,以及个人看法

    Qt 5.0+ 版本提供了 connect 的新语法,相比之前的语法新语法可以提供编译期检查,使用也更方便.可是使用过程中发现一个小问题——当某个 signal 和成员函数是重载关系的时候,qmake ...

  8. Code Snippets 代码片段

    Code Snippets 代码片段       1.Title : 代码片段的标题 2.Summary : 代码片段的描述文字 3.Platform : 可以使用代码片段的平台,有IOS/OS X/ ...

  9. SQL Server数据库定时自动备份

    SQL Server 数据库定时自动备份[转]   在SQL Server中出于数据安全的考虑,所以需要定期的备份数据库.而备份数据库一般又是在凌晨时间基本没有数据库操作的时候进行,所以我们不可能要求 ...

  10. acm的ubuntu (ubuntu16.04 安装指南,chrome安装,vim配置,git设置和github,装QQ)

    日常手贱把ubuntu14.04更新到了16.04,然后就game over了.mdzz,不然泥萌也看不到这篇博客了=.= 然后花了些时间重装了一个16.04版的,原来那个14.04的用可以用,就是动 ...