map()和parseInt()相遇的结果

先说一下结论:[1, NaN, NaN],造成这样的原因是什么呢?

首先要先理解函数的意义,map()是将数组的每个元素传递给指定的函数处理,并返回处理后的数组,原数组不改变。单纯这样看可能就会出现脑子里一开始的答案[1,2,3],但为什么不是呢,重点来了!

map()函数是将1,2,3作为元素,和下标0,1,2分别传递给parseInt()函数,其实每个效果写出来就是:parseInt('1',0),parseInt('2',1),parseInt('3',2)的结果。parseInt()函数第二个参数的意义是指明前面参数的进制,从而转化成十进制输出,区间范围是0和2-36,默认是十进制也就是0。0默认是十进制所以1还是1,1不在有效范围内所以2变成NaN,2要求前面的参数必须以二进制0和1开头开始,所以也是NaN。

事件异步引发的血案

先上一段代码,假设页面中有4个li标签猜猜输出什么?

var elements=document.getElementsByTagName('li');
var li_length=elements.length;
for (var i=0;i<li_length;++i){
    elements[i].onclick=function () {
        alert(i)
    }
}

答案:不管点哪一个一直输出4。

这其实就是事件异步引发的问题,循环过程中对DOM元素事件是绑定成功的,这一点是没有问题的,但是alert中的i却一直是以变量的形式存在的,当i经过一套for循环下来后最终的值变成了4,所以当点击事件触发,去调用i这个值时,是调用的当前变量内容,而不是覆盖之前的变量内容。

其实可以更明显一点,直接在循环外面去改变i的值,比如说在for循环下面给i赋值为999,那么当你触发点击事件时就会输出999;

当数组欺骗length时……

先上一段代码猜猜输出什么?

var arr=[];
arr[1]=9;
arr[3]=99;
arr[9]=999;
arr['a']='b';
arr['c']='d';
console.log(arr.length)

答案:10。

这里length实际上是根据数组的下标获取,而数组下标是从0开始的,所以这里获取最大下标9,然后加1最终返回的结果10。假设没有任何一个数值下标的元素,则就会输出0。

其实在js中数组的下标是不能存在字符串的,但如果我们尝试着把字符串作为下标使用,其实js会把这个认为是属性来看待,就像我们的对象一样,以键值对的形式存在。

数组的浅复制

有些代码不是单纯赋值之后就会分割成两个个体。

var arr=[1,2,3,4,5];
var arr2=arr;
arr[1]=999;
console.log(arr2[1])//999

这里虽然看上去是把arr的值赋给了arr2,实际上只是把arr的地址赋给了arr2,所以当我们改变arr的值时,arr2对应的值也会改变。

要想完全复制出来一份数组可以用以下方式:

var arr=[1,2,3,4,5];
var arr2=[...arr];
arr[1]=999;
console.log(arr2[1])//2

every()、some()以及filter()关系

every()和some()都是迭代函数,二者都是接受一个返回值为布尔值的自定义函数,对数组中的每个元素使用该函数,最终every()或some()返回一个布尔值。不同的是every()要求数组中的每个元素通过自定义函数时都返回true,那every()本身才会返回true,而some()中的自定义函数只要有一个返回true,则some()就会返回true。

function isEven(num) {
    return num % 2 == 0;
}
var nums = [2,4,6,8,10];
var nums2 = [2,4,7,8,10];
var nums3 = [1,3,5,7,9];
console.log(nums.every(isEven));//true
console.log(nums2.every(isEven));//false
console.log(nums2.some(isEven));//true
console.log(nums3.some(isEven));//false

而filter()也是迭代函数,和every()类似,但是他返回的不是布尔值,而是经过自定义函数返回值为true的元素。

function isEven(nums){
    return nums%2==0;
}
var arr=[1,2,3,4,5,6,7,8,9];
var arr2=arr.filter(isEven)
console.log(arr2)//[2,4,8]