js在前端行业中的地位无需赘言,它是前端工程师的立身之本,然而现在前端工程师用的最多的就是框架了,让很多人误以为学会了框架就是学会了前端,那么还有多少精力能放在js基础上面呢,这几年,js的能力也在突飞猛进,从我们之前的es3到现在的es10,在不停的增加新的知识点,从经典的es5以后,每年都在不停的扩展掌握更多新的知识点可以为我们的工作如虎添翼。有些人可能有这样的疑问,我们开发业务都是使用的框架,为什么要学习js基本功和全新的js呢?
我们从两个维度开分析:
- 1.对于开发,无论我们使用vue还是react亦或是node,他们背后都是使用的原生js,逻辑是原生js,框架不解决逻辑问题,掌握新的js语法,让你的开发事半功倍。
- 2.对于业务,避免不了的就是算法,即使没有算法,我们也要按照实际业务需求去做开发,关注和使用新技能,使用新技术扩宽解决问题的边界,提高解决问题的能力,保持充电的热情。
从ES6-ES10扩展了很多新技术,ES6版本对js做了很多改进和扩展,从ES7之后不会有非常完整的模块和能力的提升,但提出了很多能力上的升级,如字符串和Object等,这些都是非常有意义的。
ES6的扩展内容如下:

ES7-ES10扩展如下:

这里就对使用频率高的知识点坐做下总结和归纳。
一、数组Array
1.遍历
ES5中的遍历:
(1)for循环
let array = ['Apple', 'orange', 'banana', 'tomato', 'durian']; for(let i = 0;i<array.length;i++){ if(array[i] === 'banana'){ continue; } console.log(array[i]) } // 输出:Apple, orange, tomato, durian
优点:for循环中可以使用continue和break自由控制
缺点:语法繁琐
(2).forEach遍历
array.forEach(function(item){ console.log(item) }) // 输出:Apple, orange, banana, tomato, durian
优点:语法更简洁
缺点:forEach会将整个数组每一项都遍历一遍,遍历不受控,不支持continue和break
(3).every遍历
// demo 1 默认返回false,只输出第一项就结束 array.every(function(item){ console.log(item) }) // 输出:Apple // demo 2 要继续执行则返回true array.every(function(item){ if(item !== 'banana'){ console.log(item) } return true }) // 输出:Apple, orange, tomato, durian
every和forEachh用法很相似,同样不支持continue和break,但区别是every可以通过返回值return false/true受控,every返回值默认是返回false,要不要继续往下遍历,取决于函数体的返回值,而该函数的返回值默认是返回false,如果要改变其默认行为,继续往下遍历,则需要在函数体末尾加上return true即可。
(4).for…in遍历
for(let index in array){ console.log(index,array[index]) } /*输出: 0 Apple 1 orange 2 banana 3 tomato 4 durian */
注:该方法是专门为object设计的,虽然可以遍历数组,但是是有瑕疵的。for…in之所以可以遍历数组是因为数组也属于object,既然数组属于object,for…in也可以用于数组,那么我们可以给该数组加上一个对象a:6,即:
array.a = 6; for(let index in array){ console.log(index,array[index]) } /*输出: 0 Apple 1 orange 2 banana 3 tomato 4 durian a 6 */
我们可以这样理解,数组属于object,由于数组不是键值对形式的,所以没有key项,我们可以认为数组的下标索引值即为object的key。通过上面的例子我们发现,其实index就是key,用for…in遍历出来的index并不是数字类型,而是字符串类型,这点是很容易被很多人忽略的瑕疵,数组中使用它有一定风险,因为它是专门为object设计的,所以for…in是不建议用于遍历数组的。
优点:支持continue和break
缺点:是专门为object对象设计的,在数组中有瑕疵,不建议用于数组
ES6中的遍历:
(1).for…of遍历
后面详细介绍
2.伪数组转换成真数组
伪数组,也称类数组,它满足以下特征:
- 必须要有length属性
- 按索引方式存储数据
- 无法使用数组相关的api方法
在ES5中:
[].slice.call或者Array.prototype.slice.call进行转换
let fakeArray = { "0": "first", "1": "second", "2": "third", length: 3 }; let array = [].slice.call(fakeArray) // 或者 let array = Array.prototype.slice.call(fakeArray) // 输出真数组 ["first", "second", "third"] let domList = [].slice.call(document.querySelectorAll("span")) //NodeList // 输出所有span的数组
在ES6中:
Array.from()进行转换
let array = Array.from(fakeArray) // 输出真数组 ["first", "second", "third"]
关于Array.from语法:
Array.from(arrayLike[, mapFn[, thisArg]])
Array.from(obj, mapFn, thisArg) 就相当于 Array.from(obj).map(mapFn, thisArg)
- arrayLike:想要转换成数组的伪数组对象或可迭代对象。
- mapFn:可选,如果指定了该参数,新数组中的每个元素会执行该回调函数。
- thisArg:可选,可选参数,执行回调函数 mapFn 时 this 对象,即如果mapFn 中有this,则该this指向thisArg。
- 返回值:个新的数组实例
Array.from不仅仅是将伪数组转换成数组,还可以应用于数组的数据初始化和填充:
(1).定义一个固定长度的数组并初始化
let array = Array.from({length:5},()=>6) // [6, 6, 6, 6, 6]
(2).数组填充
let arr = ['Apple', undefined , 'banana',undefined , 'durian'] let array = Array.from(arr,(item)=>{ if(!item){ return "-" }else{ return item } }) // ["Apple", "-", "banana", "-", "durian"]
3.Array.of()创建一个新数组
在ES5中:
创建一个新数组
let array = [1,2,3,4,5] let array = new Array(1,2,3,4,5)
注:new Array()方式有一个缺陷,如果要用这种方式创建一个数组,其中就只有一个数字时,它无法做到!比如:new Array(3)只会得到一个长度为3的空数组,而不是一个长度为1的数组(其中的项为数字3)。
在ES6中:
我们使用Array.of()来创建一个新数组,并初始化:
let array = Array.of(1,2,4,5,6) // [1, 2, 4, 5, 6]
4.数组填充
在ES5中:数组填充我们可以使用遍历的方法实现,这里不再赘述。
在ES6中:
(1).fill()实现数组填充:
let array = Array(5).fill(6) // [6, 6, 6, 6, 6]
可以快速的实现数据初始化填充,相当于Array.from的超级版。
fill语法:
arr.fill(value[, start[, end]])
接受三个参数:
- value:用来填充数组元素的值
- start:可选,起始索引,默认值为0
- end:可选,终止索引,默认值为 this.length
我们也可以根据条件来进行填充
let arr = ['Apple', undefined , 'banana',undefined , 'durian'] let newArr = arr.fill('-',1,4) // ["Apple", "-", "-", "-", "durian"]
数组中Array.from和fill都可以实现数组填充,那它们有什么区别呢?
const array1 = Array.from({ length:5 }, () => ({})); const array2 = Array(5).fill({}); array1; // => [{}, {}, {}] array2; // => [{}, {}, {}] array1[0] === array1[1]; // => false array2[0] === array2[1]; // => true
由 Array.from
返回的 array1
使用不同空对象实例进行初始化。之所以发生这种情况是因为每次调用时,mapFunction
,即此处的 () => ({})
都会返回一个新的对象。
然后,fill()
方法创建的 array2
使用相同的空对象实例进行初始化。不会跳过空项。
所以,当初始化数组的每个项都应该是一个新对象时,Array.from()
是一个更好的解决方案,具体使用哪个根据具体场景选择。
4.数组中查找一个元素
要在数组中条件查找是否存在满足的元素,并返回所有符合要求的元素,实现该场景的方式很多,大多数人首先想到的、也是最方便的应该就是使用ES5提供的filter了。filter功能很全面,但是也有缺点。如果数组中数据非常大,但我们只需要知道数组中有没有符合条件的元素而不关心有多少个时,选用filter其实是不合适的,filter可以满足该场景下的需求,但是并不高效,因为它不仅仅是找到满足条件的一项元素,而是会将数组全部查找一遍,从而造成资源的浪费,针对这问题,ES6新增加了一个方法来弥补这个缺陷,它就是find。
let array = ['Apple', 'orange', 'banana', 'tomato', 'durian']; let getItem = array.find(function(item){ return item === 'banana' }) // 输出 banana
find() 方法返回满足条件的数组的第一个元素的值。
find() 方法为数组中的每个元素都调用一次函数执行:
- 当数组中的元素在满足条件时 , find() 返回符合条件的元素,之后的值不会再调用执行函数
- 如果没有符合条件的元素返回 undefined
注意: find() 对于空数组,函数是不会执行的。
find() 并没有改变数组的原始值。
IE 11 及更早版本不支持 find() 方法。
未完待续…………
原创文章,作者:Ferrycoln,如若转载,请注明出处:https://ms200.cn/archives/1712