let
let: 专门代替var,声明变量
为什么: var有两个广受诟病的缺陷:
1. 声明提前——打乱了正常的执行顺序
2. 没有块级作用域——块内和块外的变量就会互相干扰
let的特点:
1. 用let声明的变量不会被提前,也就不能提前使用
如果提前使用报错:
Cannot access 'a' before initialization
能 不 访问 a 之前 初始化
//不能在a初始化之前,访问a
在函数内:
let a=xx之前,到function(){内部,这篇区域是变量a的禁区。决不允许使用变量a。即使有全局变量a,也会报错!所以,如果局部变量和全局变量重名时,必须有一个变量要改名以示区分。
2. 添加了块级作用域:
块级作用域: if(){} while(){} for(){} ...
凡是这些块级作用域中的变量,都自成体系,不会影响外部!
原理: let相当于匿名函数自调!
补充
let a;
let b,c,d;
let e=100;
let f=333,g='3333',h=[];
// 01:变量不能重复声明
// 02:块级作用域 ,
// es5中三种作用域:全局,函数,eval作用域(是在es5的严格模式下)
// if else whille for
// {
// // 只在代码块中有效 外面读取不到
// let girl='1111';
// }
// console.log(girl); //报错
// 03:不存在变量提升
// console.log(aa); //undefind
// var aa='dddd';
// 04:不影响作用域链
{
let school='学校';
function fn(){
console.log(school);
}
fn(); //学校
}
箭头函数
2. 箭头函数: 代替一切函数定义:普通函数定义,匿名函数自调,回调函数
口诀:
1. 去function 变为 ()=>{ ... }
2. 如果只有一个形参,可省略()
3. 如果函数体只有一句话,则可省略{}
但如果仅有的一句话是return,则必须去掉return
let pow=(n)=>{n*n}; //36
console.log(pow(6));
箭头函数特点: 让内部this和外部this保持一致!
今后,只要希望回调函数内的this,和外部的this保持一致时,就可将回调函数改为箭头函数。让内部this与外部this保持一致!
但是,如果就是希望函数内的this与函数外的this不同时,就不能改成箭头函数!
比如: 对象中的方法不能改成箭头函数
01:this是静态的,this始终指向函数声明时所在作用域下的this的值
function genName(){
console.log(this.name);
}
let getName1=()=>{}{
console.log(this.name);
}
window.name="一一一";
const school={
name:'111'
}
//直接调用
getName(); //----
getName1();
call方法调用
getName.call(school); //111
getName1.call(school); //---
//02:不能作为构造实例化对象
let person=(name,age)=>{
this.name=name;
this.age=age;
}
let me=new Person('xiao',30); //报错
//03:不能使用arguments变量
let fn=()=>{
console.log(argumnts);
}
fn(1,2,3); //报错
//04:箭头函数的简写
简化对象的写法
允许在大括号里面,直接写入变量和函数,作为对象的属性和方法
这样的书写更加简介
let name='紫薯';
let meal=function(){
console.log("想吃吗");
}
const school={
name,
meal,
//imporve:function(){}
imporve(){console.log('省略:function')}
}
解构
es6允许按照一定模式从数组和对象中提取值,对变量进行赋值
这被称为解构赋值
数组的解构
const arr=['aa','bb','cc','dd'];
let [A,B,C,D]=arr;
console.log(A); //aa
console.log(B); //bb
console.log(C); //cc
console.log(D); //dd
对象的解构
const p={
name:'rrr',
age:19,
fun:function(){
return '这里用的较多'
}
}
let {name,age,fun}=p;
let {fun}=p;
fun();
3. for of: 专门简化for循环,遍历数组
遍历索引数组: 3种:
1. 普通for: for(var i=0;i<arr.length;i++)
场景: 什么都可以做:
顺序 倒叙
依次递增,也可以2,4,6 也可以5 10 15 20
2. forEach: arr.forEach((elem,i,arr){ ... })
场景: 即获得元素的内容,又需要使用元素的位置时
局限: 只能从头到尾,依次遍历!
3. for of:
场景: 仅关心每个元素的内容,不关心位置时
for(var elem of arr){
of会依次取出arr中每个元素的内容
局限: 无法获得当前正在遍历的位置
}
以上三个专门遍历索引数组
遍历关联数组或对象,必须用for in
for in只能遍历关联数组,不能遍历索引数组:
in的本意是找属性的意思,且不仅找自有属性,还找原型链上的共有属性。
for…in
const arr=[1,2,3];
for(let index in arr){
// index 索引值
// arr[index]
}
const obj={
name:"小小",
age:22,
gender:'女'
}
for(let item in obj){
// console.log(item);// name age gender
// console.log(obj[item]); //小小 22 女
}
for…of
const arr1=[1,2,3];
for(let item of arr1){
// console.log(item,'11'); //1,2,3
}
const obj1={
name:"小小",
age:22,
gender:'女'
}
//报错://obj1 is not iterable 对象是不可迭代对象
for(let item of obj1){
console.log(item);// name age gender
}
二者的区别
for...in 遍历得到key
for...of 遍历得到value
遍历对象 for...in可以 for...of不可以
遍历Map Set for...of可以 for...in不可以