2020.9.21陈悦玲
ES6
模板字符串
- 模板字符串格式
var age = 33;
var str= = `我叫陈哥`
console.log(`我叫陈哥,今年${age}`)
-
模板字符串特点
let
-
什么是let?
let用于代替var,用于声明变量的新关键词,不会存在变量提升 -
var的两个缺点
-
变量声明提前,打乱了程序正常的执行顺序
-
没有块级作用域,代码块内的变量,会影响块外的变量
-
变量提升举例
for(let i = 0;i<10;i++){
console.log(i)//0-9
}
console.log(i)//报错
//以后写程序都用let不用var 只要声明变量都用let代替var
- let原理
- let会被自动翻译为匿名函数自调
-
双保险,let为了进一步避免可能的冲突将变量悄悄改了名字:let t = 0 —> let _t = 0;
-
let特点
-
全局写let t=0,用window.t却找不到
-
同一级作用域内,不能在 let t=0 前,提前使用t。即使外层作用域有t变量,也不行
-
相同作用域内,不允许重复let同一个变量
-
注意事项:let有个兄弟const,专门用于声明一个值不能修改的常量。同时也具有let的特点,不会被声明提前,添加了块级作用域
-
案例:
//第一步获得button按钮
var btn = document.getElementsByTagName("button");
// 用var
//{}并不是块级作用域,全局依然可以找到
//使用var声明的变量时在全局下,当我们开始找的时候,就已经在全局之下执行完成for循环了
for(var i=0;i<btn.length;i++){
btn[i].onclick=function(){
console.log(`点击了第${i+1}个按钮`)
}
}
// 用let
for(let j=0;j<btn.length;j++){
btn[j].onclick=function(){
console.log(`点击了第${j+1}个按钮`)
}
}
箭头函数
- 箭头函数如何使用
- 去掉 function,在 () 和 {} 之间加 =>
- 当形参只有一个的时候可以省略()
- 当函数内部是return时,可以省略return不写
-
当函数内部只有一条语句时,可以省略{}(就像if语句省略{}一个道理)
-
数组排序
//funtion(){} var arr = [1,2,5,3,4,6];
arr.sort((a,b)=>{
return a-b
})
//当只有一个参数的时候可以省略()
console.log(arr) -
简化:
//箭头函数
function show(a){
a(1)
}
// show(function(b){
// console.log(b)
// })
//简化
// show((b)=>{
// console.log(b)
// })
//简化
show(a=>console.log(b))
- 什么时候使用?
几乎所有回调函数都可以用 => 来简化
注意:一定要记得去掉结尾的分号- 箭头函数的问题:
箭头函数是一把双刃剑,箭头函数内外this是相通的。如果希望函数内外的this保持一致时,可以不用bind()换,而直接改为箭头函数即可。如果不希望函数内外的this一致,就是希望内部的this和外部的this不一样时,不能改为箭头函数
- 箭头函数的问题:
//this->window
var lilei={ //不是作用域
sname: "Li Lei",
friends:["欣欣","峰峰","丁丁"],
// say:function(){
say(){
// 今后ES6中所有对象的方法不用加":function"
// 但是这个简写不改变this,绝不等于箭头函数
// Li Lei认识欣欣
// Li Lei认识峰峰
// Li Lei认识丁丁
// 遍历lilei好友列表中每个朋友
this.friends.forEach(
// function(f){console.log(`${this.sname}认识${f}`)}
//函数内的this指向window,用bind改变this的指向
f=>console.log(`${this.sname}认识${f}`)
// 希望this和say中的this保持一致都指lilei
)
}
}
lilei.say();
var button = document.getelementbyid("button")
button.addEventListener(functon(){
console.log(this)
}//this指向button
button.addEventListener(()=>{
console.log(this)
}//this指向window
for of
var li = document.querySelectorAll("#ul>li");
var str = "hello word";
var arr = [2,4,5,9,3];
var obj={
name:"kiki",
age:12
}
for(var key of arr){
console.log(key)
}
- 对比循环
- for循环
- arr.forEach()
- for of 局限:无法获得当前遍历的位置;是ES6的功能,不是所有浏览器,所有数组和类数组对象都支持
for of和for循环一样的,可以遍历数组、类数组对象、字符串,但是不能遍历对象和关联数组- for in 只能遍历关联数组和对象,in其实不仅遍历当前对象自己的成员,且会延着原型链向父对象继续查找所有可用的成员名
-
for循环、for of、forEach三种遍历,哪种效率高?
答:一样高。其实只有一种遍历,就是for循环。其他的都是封装的for循环而已。所以,ES5的其他遍历函数 indexOf、every、some、forEach、 map、filter 和 reduce,都没有效率的提升,因为内部都是for循环而已,只是语法简单而已 -
是不是有了ES6,就不用ES5了?
答:要看浏览器是否兼容ES6。如果使用框架和微信开发,基本上可以使用最新的语法。因为框架中和微信开发中都自带翻译工具(Babel),在项目打包时,会将ES6代码翻译成ES5代码,保证浏览器兼容性。如果没使用框架,使用原生或jquery开发,则尽量不要使用ES6
参数增强
- 参数默认值
- 什么是参数默认值(default)?
ES6允许为函数定义中形参列表的最后一个参数定义默认值,如果没有传递实参,则自动调用形参的默认值
function fn(a,b,c=0){...} - 使用
定义:function 函数名(形参1,形参2,...,形参n=默认值)
提示:如果调用函数时,没有提供最后一个实参,就自动用默认值代替
html
//形参默认值
function add(a,b,c=10){
console.log(a+b+c)
}
add(1,2,3)//6
add(1,2)//13
调用函数时,如果没有传入最后一个实参值,则自动使用默认值代替
兼容性写法:
function add(a,b,c){
//兼容性写法
c=c||10
//或者写 c === undefined && (c=10)
console.log(a+b+c)
}
add(1,2,3)//6
add(1,2)//13
案例
//点餐案例
function order(zhushi,xiaochi,yinliao="可乐"){
console.log(`您点的套餐为:
主食:${zhushi}
小吃:${xiaochi}
饮料:${yinliao}
`)
}
order("米饭","鸡腿")
-
剩余参数
专门代替arguments的语法,代替arguments处理不确定参数个数的情况
- 定义函数时
从头到尾获得所有实参值
function fun(...数组名){...}
提示:...的意思是”收集”,把传给函数的所有实参值都收集到...后的数组中保存
//剩余参数
var arr=[]
function order(...arr){
console.log(arr)
}
order("套餐1","套餐2","套餐3")
剩余参数可以只收集部分实参值
function 函数名(形参1,形参2,...数组名){...}
提示:...数组名 收集的是除了之前形参1和形参2对应的实参值之外的所有剩余的实参值
注意:保存剩余实参值的结构是一个纯正的数组,可用数组家全部APi
var arr=[]
function order(taocan1,taocan2,...arr){
arr.forEach(function(elem,i){
console.log(elem+i)//元素值+下标
})
}
order("套餐1","套餐2","套餐3","套餐4")//套餐32套餐43
案例1:使用剩余参数语法求和
var arr=[];
function add(...arr){
console.log(arr)
var result = arr.reduce(function(prev,elem,i,arr){
return elem+prev;//prev是前一个参数,elem是当前参数值
})
return result;
}
console.log(add(1,2,3,4))//10
案例2:计算员工薪资,包含姓名和基本工资(bonus),以及其他来源工资(送外卖,跑滴滴,兼职...),使用剩余参数来实现
var arr=[];
function add(name,jibengongzi,...arr){
var result = arr.reduce(function(prev,elem){
return prev+elem
})
var sum=result+jibengongzi
// return sum;
console.log(`${name}的总工资是${sum}`)
// return `${name}的总工资是${sum}`
}
// console.log(add("lili",2000,1,2,3,4))
add("lili",2000,1,2,3,4)
//用for循环做
var arr=[];
function add(name,jibengongzi,...arr){
// var result = arr.reduce(function(prev,elem){
// return prev+elem
// })
// var sum=result+jibengongzi
// //用for循环做
for(var i=0;i<arr.length;i++){
var result=result+arr[i]
}
var sum = result+jibengongzi;
// return sum;
console.log(`${name}的总工资是${sum}`)
// return `${name}的总工资是${sum}`
}
// console.log(add("lili",2000,1,2,3,4))
add("lili",2000,1,2,3,4)
add("bibi",3000,1,2,3,4,5)
-
打散数组
什么是打散数组?将一个数组打散为多个元素值,依次传给函数的多个形参变量,代替apply
为什么使用打散数组?
apply()也能打散数组参数,再传给要调用的函数。但是,apply()的本职工作是修改this,然后顺便帮忙打散数组。如果今后我们只想单纯的打散数组,跟this无关时。apply()就不好用了。如果用apply()单纯打散数组,必须给定一个无意义的对象作为第一个参数
Math.max.apply( ? ,arr)
var arr=[4,6,2]
console.log(Math.max.apply(null,arr))//(this指针的方向,数组)
什么时候使用打散数组?
当一个函数不支持数组参数,而给定的实参值却是放在一个数组中的时候,都要先打散数组,再使用多个值
Math.max(...arr)
...先将数组打散为单个值,再传入前边的函数。好处是,...和this无关,只是专门单纯的打散数组
使用打散数组
(要考)
函数名(...数组)
复制数组:
第一种:var arr1 = arr.slice();
第二种: var arr1=[...arr]
合并两个数组
第一种: var arr3=[].concat(arr1,arr2)
第二种: var arr3=[...arr1,...arr3]
浅克隆一个对象
var obj1 = {...obj}
合并两个对象
第一种: var obj3 = Object.assign({},obj1,obj2)
将obj1和obj2打散后,所有的属性,都放入第一个参数空对象中返回
Object.assign方法用于对象的合并,第一个参数是目标对象,后面的参数都是源对象
第二种: var obj3={...obj1,...obj2}
笔试题:
-
...不是打散的意思吗?这里怎么成了收集?
定义函数时,形参列表中的...是收集不确定个数的实参值的意思。调用函数时,实参值列表中的...是打散数组实参为多个实参值,分别传入的意思
-
...作为打散数组放在实参列表中时,不一定放在结尾?
是的,可以和其他单独的实参值混搭
近期评论