ES6
ES6
ES6是什么,为什么要学习它,不学习会怎样?
ES6是新一代Javascript标准,对js语言的核心内容做了优化升级,规范了js的使用标准,新增了一些js原生方法,使得js更加规范,更加适合大型应用。学习ES6是成为专业正规军的必经之路。不学习ES6也能打鬼子,但只能当一个游击队长。
ES5、ES6和ES2015有什么区别?
ES2015特指在2015年新发布的新一代js标准,ES6泛指下一代js标准,ES6包括ES2015、ES2016、ES2017、ES2018等,某部分人认为ES7就是ES2016,ES8就是ES2017等类推(这样不标准)
babel有什么用
babel是一个ES6转码器,可以将ES6高级代码转为ES5低端代码,以便兼容那些低版本浏览器。
let有什么用,为什么有了var还要使用let
在ES6之前,声明变量只能用var,var声明变量有很多不合理的点,准确的说是因为ES5中没有块级作用域是很不合理的,甚至可以说是一门语言级别的bug(这也是很多C++,java开发人员看不懂,瞧不起JavaScript语言的原因之一)。
没有块级作用域会带来很多难以解释的问题,比如for循环var变量泄漏,变量覆盖问题,let声明的变量拥有自己的块级作用域,且修复了var声明带来的变量提升问题。
console.log(a)//报错
let a
//let不存在变量提升,var存在
console.log(a)//undefined
var a
举一下ES6对String字符串类型做的常用升级优化
优化部分
ES6新增了字符串模板,在拼接大段字符时,用反引号(`)取代以往的字符串相加的形式,能保留所有空格和换行,使得字符串看起来更加直观,优雅。
var x=100
div1.style.width=x='px'
//用ES6模板字符串
div1.style.width=`${x}px`
//传统写法,不允许换行,读写性差
li.innerHTML= '<div class="topPipe" style="height: '+topHeight+'px"><img src="img/up_pipe.png" alt=""></div> <div class="bottomPipe" style="height: '+bottomHeight+'px"> <img src="img/down_pipe.png" alt=""> </div>'
//ES6模板字符串,允许换行和空格,读写性强
li.innerHTML = `
<div class="topPipe" style="height: ${topHeight}px">
<img src="../public/img/up_pipe.png" alt="">
</div>
<div class="bottomPipe" style="height: ${bottomHeight}px">
<img src="../public/img/down_pipe.png" alt="">
</div>
`
升级部分
ES6在String原型上增加了includes()方法,用于取代传统只能用indexOf查找包含字符串的方法(indexOf返回-1表示没查到,不如includes()返回false更明确,语义更清晰),此外还新增了endsWith(),startsWith(),padStart(),padEnd(),repeat()等方法,可更加方便的用于查找、补全字符串。
let str='Hello,world!'
//console.log(str.indexOf('o'))4
//console.log(str.indexOf('m'))//-1
//console.log(str.includes('o'))//true
//startsWith判断是否以某字符串开始
console.log(str.startsWith('Hello'))//true
//正则必须以^开始,以$结尾
console.log(/^Hello/.test(str))//true
console.log(/!$/.test(str))//true
//endsWith判断是否以某字符串结束
console.log(str.endsWith('!'))//true
const arr=[]
for(let i=1;i<+12;i++){
arr.push((i+'').padStart(5,'0'))
//padStart(位数,填充物)
}
console.log(arr)
//padend是后面填充
//repeat()
//将字符串自我复制n次
console.log(str.repeat(4))//Hello world!Hello world!Hello world!Hello world!
ES6对Array数组做的升级优化
优化部分
数组的解构赋值
ES6可以直接以下形式进行变量赋值
let [a,b,c]=[1,2,3]
console.log(a,b,c)//1,2,3
//传统
let arr=[1,2,3]
let a=arr[0],
let a=arr[1],
let a=arr[2]
在声明较多变量时,不需要再写很多let(或var),且映射关系清晰,支持赋默认值
扩展运算符
ES6新增的扩展运算符(...),
可以轻松的实现数组和松散序列(比如集合等)的相互转化,可以取代arguments对象和apply方法,轻松获取未知参数个数情况下的参数集合。(尤其时在ES5即传统js中,arguments不是一个真正的数组,而是一个类数组的对象,但是扩展运算符的逆运算却可以返回一个真正的数组)。扩展运算符还可以轻松实现数组的复制和解构。
let arr=[1,2,3]
let brr=arr//指针
brr[0]='a'
console.log(arr)//['a',2,3]
let crr=[...arr]
crr[0]='c'
console.log(arr,crr)
var drr=[]
/*for (var i = arr.length - 1; i >= 0; i--) {//反序性能略优于正序
drr.unshift(arr[i])
//[3]
//[2,3]
//['a',2,3]
}*/
for (var i = 0;i<arr.length;i++) {
drr.push(arr[i])
}
drr[1]='d'
console.log(arr,drr)
const err=[1,2,3,4]
const [a,b,...c]=err
console.log(a,b,c)
//剩余部分都在c里面了
升级部分
ES6在Array原型上新增了find()方法,用于取代传统只能indexOf()查找数组项目的方法,且修复了indexOf查找不大NaN的bug
[1,2,3,NaN,4,5].indexOf(NaN)= = =-1//true
此外,还新增了copyWithin(),includes(),fill(),flat()等方法,可方便用于数组的查找,补全和转换等。
//copyWithin()
const arr=['a','b','c','d','e','f','g']
//用b、c把e、f替换掉
/*arr[4]=arr[1]
arr[5]=arr[2]
*/
//arr.copyWithin(指定插入目标位置索引,从哪里开始复制,复制到哪里结束)
arr.copyWithin(4,1,3)
console.log(arr)//[a,b,c,d,b,c,g]
//fill()
const arr=['a','b','c','d','e','f','g']
//用'y'把def替换掉
arr.fill('y',3,6)
console.log(arr)
//flat()多维数组降维
const arr=['a','b',['c','d'],'e','f','g']
console.log(arr.flat())//['a', 'b', 'c','d', 'e', 'f','g']
const brr=['a','b',['c','d',['e','f'],'g']]
console.log(brr.flat())//[ 'a', 'b', 'c', 'd', [ 'e', 'f' ], 'g' ]
console.log(brr.flat().flat())//['a', 'b', 'c','d', 'e', 'f','g']
console.log(brr.flat(Infinity))//['a', 'b', 'c','d', 'e', 'f','g']
ES6对Number数字做的升级优化
优化部分
ES6在Number原型上新增了isFinite(),isNaN()方法,用来取代ES5中的isFinite(),isNaN()方法检测数值是否有限,是否是NaN。
//ES5
console.log(isNaN('NaN'))//true
console.log(isNaN(NaN))//true
//ES6
console.log(Number.isNaN(NaN))//false
console.log(Number.isNaN("NaN"))//true
Number.isFinite()与上述类似,是判断数字是否有限。
升级部分
ES6在Math对象上新增了Math.cbrt(),Math.trunc(),Math.hupot()等运算方法,求立方根,求和立方根,等等
console.log(Math.cbrt(27))//3 开立方
console.log(Math.trunc('27.4567890px'))//NaN
console.log(Math.trunc('27.4567890'))
console.log(Math.trunc(27.4567890))//取整
console.log(Math.trunc(0.4567890))
console.log(Math.trunc(-27.4567890))
console.log(Math.trunc(NaN))
console.log(Math.hupot(3,4))//5 平方和开方
ES6对Object对象类型升级优化(重要)
优化部分
对象属性变量式声明
ES6可以直接以变量形式声明对象属性或方法,比传统的键值对形式声明更加简洁,更方便,语义更加清晰。
let [a,b]=[1,2]
let obj={a,b}
//等同于
let obj2={
a:a,
b:b
}
console.log(obj1,obj2)
对象中的方法也可以使用上述简洁写法:
//ES5
var obj1={
fun1:function(){
//语句
}
}
//ES6
let obj2={
fun2(){
//语句
}
}
对象的结构赋值
//ES5
let {a,b}={a:1,b:2}
//a=1,b=2
//ES6
var obj={a:1,b:2}
var a=obj,a,
b=obj.b
对象的扩展运算符
ES6对象的扩展运算符跟数组扩展运算符区别不大,毕竟数组也是一种特殊的对象。对象的扩展运算符一个最好用也是最常用的方法是可以轻松的去除木匾对象内部全部或部分可遍历属性,从而进行对象的合并和分解。
const person={
name:'小明',
age:18,
gender:'男',
number:1331241234,
hobbies:['唱','跳','rap']
}
const {name,gender,...others}=person
console.log(name,gender,others)
升级部分
ES6在Object对象上新增了is()方法,用来做两个对象的相等比较。而且完善了NaN!==NaN的不合理。
const obj1={
a:1,
b:2
}
const obj2={
a:1,
b:2
}
const obj3=obj2
// console.log(obj1==obj2)
// console.log(Object.is(obj2,obj3))
// console.log(Object.is(obj1,obj2))
console.log(NaN===NaN)
console.log(Object.is(NaN,NaN))
如何判断两个对象属性和属性值是否完全相同?(不足以判断两个对象是否完全一致)
function isObjectSame(obj1,obj2){
//判断是否是Object
//console.log(Object.prototype.toString.call(obj1))
if(Object.prototype.toString.call(obj1)!=='[object Object]'
||Object.prototype.toString.call(obj2)!=='[object Object]'){
return console.log('不是对象')
}
//判断二者是否原本就是同一指针
if(obj1===obj2){
return true
}
const arr1=Object.getOwnPropertyNames(obj1)//[a,b]可以获取obj1的所有
const arr2=Object.getOwnPropertyNames(obj2)//[b,a]
if(arr1.length!==arr2.length){
return false
}
let count=0
for(key of arr1){//把obj.a===obj2.a obj1.b===obj2.b
count=obj1[key]===obj[key]?count+1:NaN
}
if(count!==arr1.length){
return false
}
return true
}
console.log(isObjectSame([],{}))
ES6对Function函数类型升级优化
优化部分
箭头函数(核心)
1.箭头函数内的this指向的是函数定义时所在的对象,而不是函数执行时所在的对象。ES5中函数里的this总是指向函数执行时所在的对象,这使得很多情况下this的指向变得难以理解,可以归结为语言层面的bug之一。箭头函数优化了这一点,他的内部没有自己的this,这样就导致了this总是指向上一层的this,如果上一层还是箭头函数,则继续向上指,直到指向到有自己的this的函数为止,并作为自己的this;
2.箭头函数不能用作构造函数,因为没有this,无法实例化;
3.由于箭头函数没有this,所以箭头函数内也不存在arguments对象(可以用扩展运算符...代替)
函数默认赋值
在ES6之前,函数的形参时无法给默认值的,只能在内部通过变通方法实现,ES6以更简洁的方式进行函数的默认赋值
//ES5
function add(x,y){
const a=x||'请输入数字',
b=y||''
return a+b
}
//ES6
function add2(x='请输入数字',y=''){
return x+y
}
console.log(add(1,2))
console.log(add())
console.log(add2(1,2))
console.log(add2())
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 终于写完轮子一部分:tcp代理 了,记录一下
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 单元测试从入门到精通
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理