目录结构
ES6介绍
1996年11月,在ECMA的协调下,由Netscape、Sun、微软、Borland组成的工作组确定统一标准:ECMA-262,我们现在使用的JavaScript符合ECMA标准化。
1998年6月,ECMAScript 2.0版发布。
2009年12月,ECMAScript 5.0版发布。
2015年6月,ECMAScript 6.0版发布,叫做ES6,或者以年号命名叫做ECMAScript 2015。
从2015年6月之后发布的版本统一叫做ES6。
ES6中的变量和常量
1. let关键字
作用:用于声明变量,代替var关键字
特点:有块级作用域;不存在变量提升;暂时性死区
块级作用域:
- 块级作用域在ES6中才有,一对大括号就是一个块级作用域
- 在大括号中使用let声明的变量出了大括号就无效了
- 在循环、分支结构中使用let声明的变量,出了这个循环、分支也会无效
例1:
let声明的变量出了大括号就无效
{
let num=10;
}
//报错"num is not defined"
console.log(num);
var声明的变量全局有效
{
var num=10;
}
//可以打印num的值
console.log(num);
例2:
在循环结构中使用let声明的变量,出了这个循环无效
for(let i=0;i<5;i++){
}
//报错"i is not defined"
console.log(i);
var声明的变量全局有效
for(var i=0;i<5;i++){
}
//可以打印i的值
console.log(i);
变量提升:
例:
let没有声明的变量不能直接输出
//打印会报错“cannot access 'num' before initialization”
console.log(num);
let num=10;
var会将声明变量提到前面
//打印结果为undefined
console.log(num);
var num=10;
将声明提到了前面,如下代码:
var num;
console.log(num);
num=10;
暂时性死区:
let声明的变量会被绑定在块级作用域内,不受外部的影响
var num=1;
{
//因为暂时性死区导致这里的num不受外界影响,而内部的num还未定义,所以这里会报错"Cannot access 'num' before initialization"
console.log(num);
let num=10;
}
适用let的场景:
循环为所有按钮绑定点击事件,在事件中输出当前i的值
例:
<body>
<button>btn0</button>
<button>btn1</button>
<button>btn2</button>
</body>
使用let声明变量可以正确输出
<script>
//获取到所有button按钮
var btns=document.querySelectorAll('button');
for(let i=0;i<btns.length;i++){
//给每个按钮绑定点击事件
btns[i].onclick=function(){
console.log(i);
}
</script>
使用var声明变量,由于没有暂时性死区和块级作用域,循环走完后i的值为3,每次点击按钮都会打印3,如下所示:
```javascript
<script>
//获取到所有button按钮
var btns=document.querySelectorAll('button');
for(var i=0;i<btns.length;i++){
//给每个按钮绑定点击事件
btns[i].onclick=function(){
//每次都打印3
console.log(i);
}
</script>
内存图:
2. const关键词
作用:用于声明常量
特点:有块级作用域;声明常量时必须赋值,且赋值后不能修改
块级作用域
例:
{
const PI=3.1415;
}
//作用和let一样,打印报错,"PI is not defined"
console.log(PI);
声明常量时必须赋值
例:
//报错“Missing initializer in const declaration”
const PI;
赋值后不能修改
例:
const PI=3.1415;
//报错“Assignment to constant variable”
PI=3.14159264;
3. var、let、const的区别
- var和let都能声明变量,但是适用不同,在ES6以后推荐使用let声明变量
- let的特殊点:不能提升变量(保证程序的逻辑通畅)、有块级作用域(避免变量交叉污染)、暂时性死区
- const用来声明常量,常量不能改变值,有块级作用域,不能提升,初始化时常量时必须赋值
- 推荐在代码中尽量使用const
解构赋值
概念:结构赋值就是将数组或者对象中的单元分别取出并保存在单独的变量中。
1、对象解构
变量(常量)名和对象的属性名一致
例:
const{name,age,gender}={id:1,name:"小明",age:8};
console.log(name); // 小明
console.log(age); // 8
console.log(gender); // undefined
这里的变量(常量)名可以设置别名,不过使用了别名后,原名就不能使用了,如下代码所示:
const{name:username,age,gender}={id:1,name:"小明",age:8};
console.log(username); // 小明
console.log(age); // 8
2、数组解构
例:
这里前面的逗号代表前面有一个变量,所以name对应小明,age对应8
const[,name,age]={1,"小明",8};
console.log(name); // 小明
console.log(age); // 8
注意:这里的变量名可以随意设置,使用的是数组索引进行匹配的
扩展运算符
扩展运算符 …: 把后面多的值以数组的形式保存起来
例:
const[n1,n2,...n]=["张三","李四","王五","赵六","韩七"];
console.log(n1); // 张三
console.log(n2); // 李四
console.log(n); // ["王五","赵六","韩七"]
字符串扩展
1、模板字符串
模板字符串:使用反引号声明的字符串
例:
let str=`你好我好大家好!`
两个优点:
- 字符串可以换行(方便声明标签结构)
- ${}:方便解析变量或者函数
例:
<div></div>
const{name,age,gender}={id:1,name:"小明",age:8};
function sayHi(){
return `hi`;
}
//使用 ``拼接字符串可以换行,书写方便, 清晰
let str=`
<ul>
<li>姓名:${name}</li> //使用${}拼接变量(常量)
<li>年龄:${age}</li>
<li${sayHi}></li> //使用${}调用函数
</ul>
`
document.querySelector('div').innerHTML=str;
2、字符串扩展函数
常用的字符串函数:
1)includes():判断一个字符串是否包含另一个字符串
例:
const str='abcdef';
str.includes('a'); //true,str中包含'a'
str.includes('g'); //false,str中不包含'g'
2)startWith() 和 endsWith()
startWith():判断一个字符串是否以另一个字符串开始
endsWith():判断一个字符串是否以另一个字符串结束
例:
const str='abcdef';
str.startWith('abc'); //true,str是以'abc'开头
str.startWith('adb'); //false,str不是以'adb'开头
str.endWidth('ef'); //true,str是以'ef'结尾
3.repeat():返回一个新的字符串,表示将原字符串重复n次
例:
const str='abcdef';
const str1=str.repeat(2); //返回一个新的字符串:abcdefabcdef
数组函数扩展
1、数组扩展函数
1)includes:判断一个数组中是否包含某个值
例:
const arr=['a',10,20,'111','abc'];
arr.includes(10); //true,arr中包含10
arr.includes(123); //false,arr中不包含123
2)find:返回满足条件的第一个值
const arr=['a',10,20,'111','abc'];
//item:代表每次循环得到的当前单元的值
//index:代表每次循环当前单元的索引
let result=arr.find(function(item,index){
if(item>10){
return item;
}
})
console.log(result); //20
3.findIndex:返回满足条件的第一个值的索引
const arr=['a',10,20,'111','abc'];
let result=arr.find(function(item,index){
if(item>10){
return index;
}
})
console.log(result); //2
2、形参默认值
形参默认值:声明函数时给形参设置一个默认值
例:
function add(a=10,b=20){
reutrn a+b;
}
console.log(add()); //不传入实参时使用默认值,30
console.log(add(1,3)); //传入实参时使用实参,4
形参默认值练习:
let titles=[
'一大仙在公安局"跳大仙"对周围人发功说:“你今晚必死无疑”',
'小偷给关二爷下跪,给民警送锦旗',
'nginx反向代理配置中你不知道的二三事',
'女子怀疑家中进小偷,报警后发现是自己老公',
'美国男子抢劫中餐厅,因言语不通空手而归'
];
let str="";
for(let i=0;i<titles.length;i++){
str+=`
<li>
<a href="#">${titleHandle(titles[i])}</a>
</li>
`;
}
document.querySelector('ul').innerHTML=str;
//封装一个函数对标题进行处理
//判断标题长度是否超过20个字符,如果没有超过不处理
//如果超过20个字符,则截取20个字符,再拼接...
//title表示要处理的标题
function titleHandle(title,length=15,mark='~~'){
if(title.length<length){
return title;
}else{
return title.substr(0,length)+mark;
}
}
3、解构赋值和形参默认值配合
//定义函数时参数使用对象形式
function add({x,y=10}){
console.log(x+y);
}
//传入实参是对象形式
//key必须和定义函数时制定的变量名一致
add({x:10});
add({x:10,y:15});
4、rest参数
es6之前调用函数时可以传入不定数量的参数,通过在函数体内使用arguments获取多个参数
es6中取消了arguments,使用扩展运算符来接收参数
例:
es6之前
function show(){
console.log(arguments);
}
show(1,3,4,'小明') //arguments以伪数组形式保存了show中所有的参数
es6时
//...扩展运算符
//args形参,可以修改为任意变量名
function show(...args){
console.log(args);
}
show(1,3,4,'小明') //args以数组形式保存了show中所有参数
箭头函数
写法:
1、普通函数和箭头函数写法
function show(){} //普通函数
let show = () => {} // 箭头函数
2、匿名普通函数和匿名箭头函数写法
function (){} //匿名普通函数
() => () //匿名箭头函数
箭头函数特点:
1)箭头函数不能作为构造函数
构造函数:
function Person(name,age){
this.name=name;
this.age=age;
this.sayHi=function(){}
}
let p=new Person('小明',9);
以上构造函数改为箭头函数的形式会报错。
2)箭头函数没有arguments,要使用可变参数可以使用rest方式
箭头函数在Es6出现,使用可变参数不再使用arguments,而是使用rest方式
let show=(...agrs)=>{
console.log(args);
}
show(1,2,3); //[1,2,3]
3)箭头函数没有this对象,在箭头函数中的this指的函数外层的对象
例:
普通函数中:
<button>btn</button>
<script>
document.querySelector('button').onclick=function(){
//这里this指事件的调用者:button
console.log(this);
}
<script>
箭头函数中:
<button>btn</button>
<script>
document.querySelector('button').onclick=()=>{
//这里this指外层的对象:window
console.log(this);
}
<script>
4)如果函数体只有一句并且设置了返回值,则不需要使用大括号,不需要return
例:
let add=(a,b)=>{
return a+b;
}
上面的代码可以写为:
let add(a,b)=>a+b;
5)如果函数中只有一个参数,则不需要写小括号
例:
let add=(a)=>{
return a+10;
}
上面的代码可以写为:
let add = a => a+10;
定义对象的简洁方式
声明对象时,如果值的变量名和属性名相同,可以只写属性不写值
例1:
let goods="键盘";
let obj={
//前面的goods代表对象的属性,后面的goods代表前面的变量
goods:goods;
}
obj.goods; //键盘
上面代码可以写为:
let goods="键盘";
let obj={
goods;
}
obj.goods; //键盘
例2:
const id=001;
const name="小明";
const obj={
id;
name;
ad(){}
}
上面ad()函数如果使用箭头函数可以写为:
const id=001;
const name="小明";
const obj={
id;
name;
ad:()=>{}
}