一:块级作用域
块级作用域
ES5的var的作用域是函数级
ES6的let的作用域是块级的 块级通俗点说就是{}里面的东西
let和const不能重复声明会报错.且不存在变量提升
1.首先看个例子
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script>
{
/*var 不具备块级作用域的属性,所以在外面依然能访问到*/
var a=12;
}
//alert(a);
{
/*let具备块级作用域的属性,会报错 只在代码块中起作用 */
let b=12;
}
alert(b);
</script>
</head>
<body>
</body>
</html>
2.闭包问题可以用let解决
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script>
window.onload=function(){
let aBtn=document.getElementsByTagName('input');
/*这样会产生闭包,可以用立即函数来解决,但是这样增加了额外的代码
for(var i=0;i<3;i++){
aBtn[i].οnclick=function(){
alert(i);
};
}*/
//可以将var换成let 这个for每执行一次就会有个独立的i诞生,循环三次产生3个i,每个i有自己独立的值
for(let i=0;i<3;i++){
aBtn[i].onclick=function(){
alert(i);
};
}
}
</script>
</head>
<body>
<input type="button" value="a">
<input type="button" value="b">
<input type="button" value="c">
</body>
</html>
3.不影响作用域链
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
</head>
<body>
<script>
{
//在函数里作用域里没有name,会往上一级找,所以能输出
let name = "跑步";
function fn(){
console.log(name);
}
fn()
}
</script>
</body>
</html>
4.const使用
和let一样是块级作用域,不同的是声明常量,不能修改,且要赋初始值。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
</head>
<body>
<script>
//1.一定要赋初始值
//const A;//报错
//2.一般常量使用大写(潜规则)
//3.常量的值不能修改
const A = 100;
//A=200;报错
//4.块级作用域
{
const PLAYER = "UZI";
}
//console.log(PLAYER); 报错
//5.对于数组和对象的元素修改,不算做对常量的修改,不会报错
const TEAM = ["UZI", "KING", "LETME"];
TEAM.push("dd");
//但是这样会报错 TEAM='A'
</script>
</body>
</html>
二:解构赋值
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script>
/*
1.两边的结构必须一样
2.右边必须得是个东西
3.赋值和解构同时完成
数组的元素是按次序排列的,变量的取值由它的位置决定,而对象的属性没有次序,变量必须与属性同名,才能取到正确的值
*/
let {a,b}={a:12,b:13,c:5};//可以多不可以少 都是对象
console.log(a,b);
let {a,b}={12,5};//对象没有相对的属性名字是不能相匹配显示的
let [c,d]=[5,8];//数组
console.log(c,d);
</script>
</head>
<body>
</body>
</html>
例子:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
</head>
<body>
<script>
//ES6允许按照一定模式从数组和对象中提取值,对变量进行赋值被称为解构赋值
//1.数组的解构
const arr=['一','二','三','四']
let [a,b,c,d]=arr;
console.log(a);
console.log(b);
//2.对象的解构
const wu={
name:'吴签',
age:30,
jianyu:function(){
console.log('吴签什么时候进监狱');
}
}
//相当于我们声明了三个变量并且赋值
let{name,age,jianyu}=wu;
console.log(name);
jianyu()//这样解构赋值方便很多,本来需要wu.jianyu()调用
</script>
</body>
</html>
连续解构赋值:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<script>
let obj={a:{b:{c:1}}}
const {a:{b:{c}}}=obj
console.log(c);
//连续解构赋值并重命名
let obj2={a:{b:2}}
const {a:{b:data}}=obj2
console.log(data);
</script>
</body>
</html>
三:箭头函数
箭头函数就是把 function(){}
写成()=>{}
3.1不使用箭头函数
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script>
//排序
let arr=[12,8,37,26,9];
//arr.sort();//这种方法是把数字按照字符串排序的,12,26,37,8,9,只看第一个数字;
//可以这样理解,不要理解成a减b的意思,理解成在26个字母中a到b的意思,在26个字母中b比a大,所以写成a-b就是升序,写成b-a就是降序。
arr.sort(function(n1,n2){
return n1-n2;
});
alert(arr);
</script>
</head>
<body>
</body>
</html>
3.2使用箭头函数
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script>
/*
简写要求
1:如果有且仅有一个参数,()也可以不写
*/
let arr=[12,8,37,26,9];
// arr.sort((n1,n2)=>{return n1-n2;});
//2:如果有且仅有一个语句return ,{}也可以不写 arr.sort(())
arr.sort((n1,n2)=> n1-n2);
alert(arr);
</script>
</head>
<body>
</body>
</html>
3.3有且仅有一个参数的情况
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
</head>
<body>
<script>
//省略小括号,当形参有且只有一个的时候
let add=n=>{
return n*n
}
console.log(add(9));
//省略花括号,当代码体只有一条语句的时候,且return必须省略
//而且语句的执行结果就是函数的返回值
let add2=n=>n*n
console.log(add2(8));
</script>
</body>
</html>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script>
/*
function add(n){
return n+5;
}
function show(n,fn){
alert(fn(n));
}
show(12,add);
*/
//可以把以上简写成
function show(n,fn){
alert(fn(n));
}
show(12,n=>n+5)
</script>
</head>
<body>
</body>
</html>
3.4作用:修正this
普通函数this指向调用者,箭头函数的this是静态的,this始终指向函数声明时所在作用域下的this的值,用apply等也改变不了
对this起到固定的作用
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script>
console.log(this);
/*箭头函数不会改变this,函数里的this指向window,如果不用箭头函数的话就会指向json*/
let json={
a:12,
//this=>当前的环境
fn:()=>{
console.log(this);
alert(this.a);
}
}
json.fn();
</script>
</head>
<body>
</body>
</html>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script>
/*普通的function函数的this是变的,跟着执行人走,用箭头函数this是固定的,取决于在哪声明了这个函数,除非用apply等改变this指向*/
/*上一个例子this的环境是全局,只是赋值语句*/
class Json{
constructor(){
console.log(this);
this.a=12;
this.fn=()=>{
console.log(this);
alert(this.a);
}
}
}
let json=new Json();
// json.fn();
let oDate=new Date();
oDate.fn=json.fn;
oDate.fn();
</script>
</head>
<body>
</body>
</html>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
</head>
<body>
<script>
//普通函数直接调用this是指向window的 箭头函数是在全局作用域下声明的
function getName(){
console.log(this.name);
}
let getName2=()=>{
console.log(this.name);
}
window.name='全局'
const s={
name:'new'
}
//直接调用
getName()
getName2()
//call改变this指向
getName.call(s)
getName2.call(s)
//2.不能作为构造实例化对象
// let Person=(name,age)=>{
// this.name=name;
// this.age=age;
// }
// let me=new Person('xiao',30)
// console.log(me);
//3.不能使用arguments变量
// let fn=()=>{
// console.log(arguments);
// }
// fn(1,2)
</script>
</body>
</html>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
<style>
.ad{
width: 200px;
height: 200px;
background:red ;
}
</style>
</head>
<body>
<div class="ad"></div>
<script>
let ad=document.getElementsByClassName('ad')[0]
ad.addEventListener('click',function(){
setTimeout(()=>{//箭头函数是在ad.addEventListener里function这个函数作用域下声明的,所以this指向事件源ad
console.log(this);
this.style.background='green'
},1000)
})
</script>
</body>
</html>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
</head>
<body>
<script>
const arr=[1,6,8,100,23]
// const result=arr.filter(function(item){
// if(item%2===0){
// return true
// }else{
// return false
// }
// })
//箭头函数简写
const result=arr.filter(item=>item%2===0)
console.log(result);
</script>
</body>
</html>
3.5在react项目中使用箭头函数需要注意
四:rest参数和扩展运算符的使用
1.rest参数
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
</head>
<body>
<script>
//ES5获取实参的方式
function date(){
console.log(arguments);//结果为对象
}
date('hi','ur','zara')
//ES6引入rest参数,用于获取函数的实参,用来代替arguments
function date2(...args){
console.log(args);//结果为数组 可以使用数组的filter some every map方法
}
date2('hi','ur','zara')
//rest参数必须要放到参数后
function fn(a,b,...args){
console.log(a);
console.log(b);
console.log(args);
}
fn(1,2,3,4,5,6)
</script>
</body>
</html>
2.扩展运算符
扩展运算符能够将数组转换为逗号分隔的参数序列
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
</head>
<body>
<script>
const arr=['杨幂','江疏影','古力娜扎']
function actress(){
console.log(arguments);
}
actress(...arr)//与rest参数不一样的地方是rest的...在形参括号里
</script>
</body>
</html>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
<script>
//收集参数
//...必须在形参的最后一个
function show(a,b,...c){//三个点是收集剩余参数
console.log(a,b,c);
}
show(1,2,3,4,5,6,7,8);//1 2 Array(6)
</script>
</head>
<body>
</body>
</html>
数组展开
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
<script>
let arr1=[23,6,3];
function show(a,b,c){
alert(a+b+c);
}
//show(arr1);//23,6,3undefinedundefined 这样是把23,6,3全部放进a里面了
show(...arr1);//32 数组展开 相当于是show(23,6,3);
</script>
</head>
<body>
</body>
</html>
数组的合并:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
<script>
//字符串连接
let arr1=[12,5,8];
let arr2=[1,2,3];
let arr=[...arr1,...arr2];
alert(arr);
</script>
</head>
<body>
</body>
</html>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
</head>
<body>
<div></div>
<div></div>
<div></div>
<script>
//1.数组的合并
const arr = ["杨幂", "江疏影", "古力娜扎"];
const arr2 = ["梁朝伟", "古天乐"];
const actress = [...arr, ...arr2];
console.log(actress);
//2.数组的克隆
const arr3 = ["a", "b", "c"];
const arr4 = [...arr3];
console.log(arr4);
//3.将伪数组转为真正的数组
const divs = document.querySelectorAll("div");
console.log(divs);
const divArr = [...divs];
console.log(divArr);
</script>
</body>
</html>
json展开
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
<script>
let json={a:12,b:5,c:99};
/*
错误展示
alert(...json);//这样写相当于alert(a:12,b:5,c:99);这不是json,少了括号{}
*/
let json2={
...json,
d:999
};
console.log(json2);
</script>
</head>
<body>
</body>
</html>
五:原生对象扩展 (箭头函数用在这四个方法很方便)
5.1 map 映射一一对应,进去多少出来多少
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script>
let arr=[60,59,88,100,90];
/*let arr2=arr.map(function(item){
// if(item>=60){
// return '及格';
// }else{
// return '不及格';
// }
//简化 用三目运算符
// return item>=60?'及格':'不及格';
});*/
//使用箭头函数
let arr2=arr.map(item=>item>=60?'及格':'不及格');
console.log(arr);
console.log(arr2);
</script>
</head>
<body>
</body>
</html>
5.2 reduce 缩减 n---->1 进去n个,出来一个
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script>
let arr=[60,59,88,100,90];
let result=arr.reduce(function(tmp,item,index){//一开始temp是第一个数60,item是第二个数59
// alert(index+":"+tmp+":"+item);
if(index==arr.length-1){//最后一次
return (tmp+item)/arr.length;
}else{
return tmp+item;//需要计算一个结果并且返回出来作为下一步的输入
}
});
alert(result);
</script>
</head>
<body>
</body>
</html>
5.3 filter 过滤 不一定
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script>
//一个例子,只要偶数,过滤掉奇数
let arr=[60,59,88,100,90];
let arr2=arr.filter(item=>item%2==0);
console.log(arr);
console.log(arr2);
</script>
</head>
<body>
</body>
</html>
5.4 forEach 遍历循环 没有返回值
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script>
let arr=[60,59,88,100,90];
arr.forEach((item,index)=>{
// alert('第'+index+':'+item);
alert(`第${index}个:${item}`);//另一种简便写法 模板字符串 反引号(`)标识
})
</script>
</head>
<body>
</body>
</html>
5.5 json写法,json对象
JSON.stringify({a:12,b:5});//JSON转变成字符串 ,方便发送
JSON.parse(’{“a”:12,“b”:5}’);//字符串还原成JSON
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script>
/*let json={a:12,b:5,name:"blue"};//字符串要用双引号
alert(JSON.stringify(json));*/
let str='{"a":12,"b":5}';
let json=JSON.parse(str);
console.log(json);
</script>
</head>
<body>
</body>
</html>
5.6 find方法
ES6中数组方法( find )
有一个对象数组,找到符合条件的对象 (find方法找到符合条件的对象之后不在往后执行)无符合条件返回undefined
复制代码
var arr = [
{name:'jerry',sex:'man'},
{name:'jack',sex:'woman'},
{name:'jack',sex:'man'}
]
var jack = arr.find(function(obj){
return obj.name == 'jack';
})
console.log(jack); // 返回符合条件的第一个对象{name: "jack", sex: "woman"}
var bill = arr.find(function(obj){
return obj.name == 'bill';
})
console.log(bill); // undefined
六:模板字符串
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
</head>
<body>
<script>
//1.声明
let str = `我是模板字符串`;
console.log(str);
//2.内容中可以直接出现换行符
let str2 = (
`<ul>
<li>hi</li>
<li>你好</li>
<li></li>
<li></li>
</ul>`
);
console.log(str2);
//3.变量拼接
let str3='Hangz'
let str4=`${str3}hou`
console.log(str4);
</script>
</body>
</html>
七:对象的简化写法
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
</head>
<body>
<script>
//ES6允许在大括号里面,直接写入变量和函数,作为对象的属性和方法
//这样的书写更加简洁
let name='阿里'
let change=function(){
console.log('我想升职加薪');
}
const container={
name,//该对象的属性和之前name变量值一样,所以可省写
change,
improve(){
console.log('我想转行当厨师');
}
}
console.log(container)
container.change()
container.improve()
</script>
</body>
</html>
八:函数参数的默认值设置
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
</head>
<body>
<script>
// ES6允许给函数参数赋值初始值
//1.形参初始值,具有默认值的参数,一般位置要靠后
function add(a,c,b=20){
return a+b+c
}
let result=add(1,2)
console.log(result);
//2.与解构赋值结合
function connect({host="127.0.0.1",username,password,port}){
console.log(host);
console.log(username);
console.log(password);
console.log(port);
}
connect({
host:'8800',
username:'root',
password:'root',
port:3306
})
</script>
</body>
</html>