之前只有函数中存在局部作用域。
一、声明变量与常量
1.let关键字
①let关键字用来声明变量。
②if、for的大括号 { } 内用 let 声明的变量具有块级作用域,只在当前大括号内起作用。
依然遵循作用域链:内部可以访问外部,外部不能访问内部
if (true) {
let b = 10;
if (true) {
console.log(b); //遵循作用域链:内部可以访问外部。10
}
}
if (true) {
let b = 10;
if (true) {
let b = 20;
}
console.log(b); //遵循作用域链:外部不能访问内如。10
}
③在 for 循环中,用 let 声明的计数器 i 也具有块级作用域,只在当前大括号内起作用。
④let 声明的变量没有变量提升(预解析),变量必须先声明后使用。
⑤暂时性死区。块级作用域内部与全局声明的同名变量没有任何关系。
var a = 10; //全局变量
if (true) {
console.log(a); //错误!a没有定义
let a = 20;
}
2.每次循环都会产生一个新的块级作用域,每个块级作用域中的变量相互独立的。
// 核心:循环是同步任务,调用函数是异步任务。所以函数被调用时循环已经结束。
var arr1 = [];
for (var i = 0; i < 2; i++) {
arr1[i] = function () {
console.log(i);
};
}
arr1[0](); //2
arr1[1](); //2
// 核心:每次循环都会产生一个新的块级作用域,每个块级作用域中的变量相互独立的。
// 函数执行时输出的是自己上一级(循环产生的块级作用域)作用域下的i值。
let arr2 = [];
for (let i = 0; i < 2; i++) {
arr2[i] = function () {
console.log(i);
};
}
arr2[0](); //0
arr2[1](); //1
3.const关键字
①const关键字用来声明常量。
②const关键字声明的常量具有块级作用域。
③const关键字声明常量时必须赋值。
④const关键字声明的常量不能重新赋值。
如果是基本数据类型,不能更改值;
如果是复杂数据类型,可以更该内部的值,不能更改地址值,。如下:
const arr = [1,2];
arr[0] = 10;
arr[1] = 20;
console.log(arr); //结果为[10,20]
arr = [10,20]; //报错!不能更改复杂数据类型的地址值
二、解构赋值
ES6中允许从数组中提取值,按照对应位置,对变量赋值,对象也可以实现解构
4.数组解构
let [ 变量1,变量2...] = 数组
注意:如果变量的个数比数组元素多时,后面的变量赋值为underfined。
如果变量的个数比数组元素少,后面的数组元素被忽略。更多情况见文档。
let [a, b, c] = [1, 2, 3];
console.log(a) //1
console.log(b) //2
console.log(c) //3
5.对象解构
(1)let { 与属性名同名变量1, 与属性名同名变量2...} = 对象
// 声明一个对象
let obj = { uname: '吴磊', age: '22' };
//(1) 对象解构
let {uname, age} = obj;
console.log(uname); //吴磊
console.log(b); //22
(2)修改结构出来的变量名称
let { 属性名1:自定义名1,属性名2:自定义名2...} = 对象
// 声明一个对象
let obj = { uname: '吴磊', age: '22' };
//(2)对象解构
let { uname: a, age: b } = obj;
console.log(a); //吴磊
console.log(b); //22
(3)结构赋值时,给结构出来的变量添加默认值。
let { 变量名 = 默认值 } = 对象 ( 如果对象中没有要结构的这个变量,则该变量取默认值。)
(4)防止被结构的对象出错,结构时预处理
let { 变量名 } = 对象 || {}
//如果被解构的对象为null或者undefined时,结构赋值会报错。
const obj = null
const {data} = obj || {}
三、箭头函数
1.格式
const 变量名 = 参数 => 函数体
①箭头函数的函数体只有一句代码,并且这句代码的结果就是函数返回值的话,可以省略大括号和return。
②箭头函数只有一个参数,可以省略小括号。
// 下面两个函数时等价的
function sum(num1, num2) {
return num1 + num2;
}
const sum = (num1, num2) => num1 + num2;
2.箭头函数中的this
箭头函数中不绑定this,箭头函数中的this指向是它所定义的位置的this。
也就是,定义箭头函数中的作用域的this指向谁,它就指向谁。
// 箭头函数的this指向所在作用域的this.但是obj对象不产生作用域,所以箭头函数的this指向window。
var age = 100;
var obj = {
age: 22,
say: () => {
console.log(this.age);
},
};
obj.say();
四、剩余参数
1.剩余参数与箭头函数搭配
箭头函数里没有arguments内置对象,所以参数个数不确定时可以用"...参数名"接收剩余所有参数,存储到一个数组中。
const sum = (...args) => {
let total = 0;
args.forEach(value => total += value); //遍历参数数组,实现求和
console.log(total);
};
sum(21,34,64)
2.剩余参数可以和解构一起使用。
当变量个数小于数组元素个数时(对象属性个数),用剩余参数接收剩下的所有数组元素(对象属性),存储到一个新数组中。
let [...变量名] = 数组
let arr = [1, 2, 3, 4];
let [a, ...b] = arr;
console.log(a); // 1
console.log(b); // [2,3,4]
let obj = {uname: '吴磊',age: 22}
let{...c} = obj;
console.log(c); //object{uname: '吴磊',age: 22}
五、数组的扩展方法
1.数组的扩展运算符...(对象也有)
格式:...数组名
①扩展运算符可以将数组或者对象转为用逗号分隔的参数序列。
②console.log打印时,会把逗号当做分隔符自动抹去。
let arr = [1,2,3,4];
// ...arr //相当于1,2,3,4
console.log(...arr); //输出结果为:1 2 3 4
2.数组扩展运算符的应用----合并数组
(1)let arr3 = [ ...arr1 , ...arr2 ]
(2)arr1.push( ...arr2 )
// 合并数组方法1
let arr1 = [1, 2, 3];
let arr2 = [4, 5, 6];
let arr3 = [...arr1, ...arr2];
console.log(arr3);
//合并数组方法2
let arr4 = [10,20,30];
let arr5 = [40,50,60];
arr4.push(...arr5);
console.log(arr4);
3.数组扩展运算符的应用----伪数组转换成数组
let 数组名 =[ ...伪数组]
//伪数组转换成数组
var lis = document.querySelectorAll('li');
lis = [...lis];
4.数组的Array.from( )方法 (人资项目的日历会用到)
Array.from ( 伪数组,处理函数 )
(1)Array.from( )方法可以将伪数组转换成数组,返回值是新数组。
(2)第一个参数是待转化的伪数组。
(3)第二个参数是一个函数,可以对每一个伪数组元素进行处理并返回到新数组中。
// 定义一个伪数组
var arrayLike = {
"0": 1,
"1": 2,
"length": 2,
};
// 将伪数组转换成真数组,并把每一个元素乘以2
var newarr = Array.from(arrayLike, (value,index) => value * 2);
console.log(newarr);
5.数组的find( )方法 (重点)-------------------->数组的some( )方法
数组名.find( function( item , index ))
(1)find( )方法可以查找数组中【第一个】满足条件的元素。
(2)方法的返回值是第一个满足条件的数组元素。
(3)方法的参数是一个处理函数。方法会遍历数组,每个元素都会调用处理函数。
(4)处理函数有两个参数,当前数组元素item,当前数组元素的索引号index。
(5) 结果一定要 return 出去。
var arr = [{ id: 1 }, { id: 2 }];
var ele = arr.find(function (item, index) {
return item.id == 2;
});
console.log(ele); // {id: 2}
6.findIndex( )方法
数组名.findIndex( function( item ,index ) )
(1)与find( )方法用法完全相同。只不过findIndex( )方法查找的是索引号。
(2)findIndex( )方法的返回值是第一个满足条件的元素的索引号。找不到则返回-1。
var arr2 = [10, 20, 30, 40];
var i = arr2.findIndex((item) => item > 20);
console.log(i); // 第一个大于20的元素的索引号是2
7.includes( )方法
数组.includes( 元素 )
includes( )方法可以查找数组中是否包含某个元素。返回值是布尔值。
some( )方法可以查找数组中是否有 符合条件的元素。找到一个,则不再遍历剩余元素。
includes( )方法可以查找数组中是否有 某个元素。
map( ) 和 filter( )
六、字符串的扩展方法
1.模板字符串
2.startsWidth( )方法和endsWidth( )方法
原字符串.startsWith(参数字符串):表示参数字符串是否在原字符串的头部,返回布尔值
原字符串.endsWith(参数字符串):表示参数字符串是否在原字符串的尾部,返回布尔值
3.repeat( )方法
var 新字符串 = 原字符串.repeat( 次数 )
repeat( )方法可以将字符串重复n次。参数表示重复的次数,返回值是一个新字符串。
3.Set数据结构
- Set本身是一个构造函数,用来生成 Set 数据结构。
- Set类似于数组Array,但是成员的值都是唯一的,没有重复的值。
①参数是一个数组。
②返回值是一个Set数据结构。
var 变量名 = new Set( [... ] )
const set = new Set([1,1,2,2]);
console.log(set.size); //返回Set数据结构的长度
console.log(set); //返回Set数据结构本身 {1, 2}
var arr = [...set]; //数组去重
console.log(arr);
4.利用Set数据结构、解构 进行数组去重
var Set数据名称 = new Set(数组)
数组 = Array.from(Set数据名称)
5.Set结构的方法
- add(value):添加某个值,返回 Set 结构本身
- delete(value):删除某个值,返回一个布尔值,表示删除是否成功
- has(value):返回一个布尔值,表示该值是否为 Set 的成员
- clear():清除所有成员,没有返回值
const set = new Set(["a","b"]);
//添加值。可以连写。
set.add('C').add("D");
// 删除值,返回一个布尔值,表示是否删除成功。
const result = set.delete('C');
console.log(result);
// 判断Set中是否存在该参数。返回一个布尔值。
const result2 = set.has('a')
console.log(result2);
// 清除Set结构中的所有值。
set.clear();
6.遍历Set结构
Set 结构名.forEach( function( value ) { } )
Set结构也有forEach( )方法,但参数只有一个,表示当前元素。