let和const的使用
let和var的区别?
- let声明的变量只在当前(块级)作用域内有效
- let声明的变量不能被重复声明(包括普通变量和函数参数)
- 不存在变量提升(注意考虑暂时性死区)
- 不能当成window的属性(用var声明的全局变量是window的属性)
1、只在块级作用域内有效
{
let a = 10;//局部变量
}
console.log(a);//访问报错
2、不能被重复声明
let a = 10;
let a = 20; //报错
3 、不存在变量提升
console.log(a); //报错
let a = 10;
暂时性死区
es6规定,如果块级作用域当中,有let、const声明的变量,这个变量一开始就会形成封
闭的作用域,这块封闭的作用域无视外部的同名变量,同时在声明的前面不能使用该变
量,是一块死区。
let monkey = 'I am a monkey'
{
console.log(monkey) //报错
let monkey = 'I am anthor a monkey'
}
let的常见运用
循环遍历 点击每一个li,输出对应的索引
var aLi = document.querySelectorAll("li");
for (let i = 0; i < aLi.length; i++) {
aLi[i].onclick = function () {
console.log(i);
}
}
这段代码相当于下面的代码
{
let i = 0;
aLi[i].onclick = function () {
console.log(i);
}
{
let i = 1;
aLi[i].onclick = function () {
console.log(i);
}
}
//...
const 是用于声明常量,常量是值不可变的量,试图改变常量的值都是不被允许的。其用法参照于let的使用
const ID = 101110120110120120213203; //只能读,不能改
const obj = {
a: 1
};
obj = {
//改变了地址,报错
a: 2
};
// obj.a = 2;//地址并没有改变,所以这种操作不报错
解构赋值
数组的解构赋值
用法
let data = [1, 2, 3];
let [a, b, c] = data;
console.log(a, b, c); // 1 2 3
es6之前的写法
let arr = [1,2,3];
let a = arr[0];
let b = arr[1];
let c = arr[2];
默认值
let [a, b = 1] = [3]; //默认将b赋值为1
注意:默认值只有当这个变量取得值是undefined时,才会取默认值
let c;
let [a = 3] = [c]; // a=3,不是undefined,取了默认值
运用:交换变量
let a = 20;
let b = 10;
[a,b] = [b,a] //a=10 b=20
es6之前交换变量
let a = 20;
let b = 10;
let temp;
temp = a
a = b
b = temp
运用:接收多个函数返回值
function getUserInfo(id){
return [
true,
{
name:'小明',
gender:'女',
id:id
}
'请求成功'
]
}
const [status,data,msg] = getUserInfo(123)
对象的解构赋值
用法
let {
a,
b
} = {
a: 1,
b: 2
};
console.log(a, b); //1 2
以上代码相当于
let {
a:a,
b:b
} = {
a: 1,
b: 2
};
console.log(a, b); // 1 2
ES6中,如果属性名和属性值是相同的字符时,这时可以简写。同时对于方法,也可以进行简写,如下
//ES6对象的编写方式
let obj = {
a,
foo() {
}
}
console.log(obj);
//es6之前的写法
let obj = {
a,
foo: function () {
}
}
默认值
let {
a,
b = 5
} = {
a: 1
};
console.log(a, b); //1 5
当解构赋值时,对应的变量取得undefined时,触发取默认值
运用:函数传参
let obj1 = {
a: 1,
b: 2
};
function foo({
a , b}) {
console.log(a);
}
foo(obj1);
ES6新增的一些操作方法
字符串相关
var str = "abc";
console.log(str.includes("a"));
console.log(str.includes("d")); //是否含有某字符
console.log(str.startsWith("a")); //以某字符开头
console.log(str.endsWith("a")); //以某字符结尾
console.log(str.repeat(3)); //重复3次
console.log(str.padStart(10, "0")); //从字符串头部添加0这个字符,补足10位
console.log(str.padEnd(10, "0"));
函数相关
形参的默认值
函数在使用时如果不传宽高,就用一个默认值去代替
function foo(domobj, width = 100, height = 100) {
//参数默认值,传实参用实参,不传实参用默认
domobj.style.display = "block";
domobj.style.width = width + "px";
domobj.style.height = height + "px";
}
ES6之前,我们只能如下这样写,可以看出代码很长
function foo(domobj, opts) {
var defaults = {
width: 100,
height: 100
};
if (opts === undefined) {
opts = {
};
}
var options = {
};
for (var i in defaults) {
options[i] = opts[i] || defaults[i];
}
domobj.style.display = "block";
domobj.style.width = options.width + "px";
domobj.style.height = options.height + "px";
}
形参的个数
function foo(x, y) {
}
console.log(foo.length); //形参的个数 2 */
rest参数
function foo(a, ...rest) {
console.log(arguments); //包含所有实参的一个伪数组
console.log(rest); //表示剩余的实参的一个数组
}
foo(1, 2, 3);
1、arguments获取的是实参的伪数组,不能使用数组的一些方法,如push、pop、splice、slice等方法
2、rest参数只放在形参的最后,否则会报错
数组相关
let aDivs = document.getElementsByTagName("div");
//第一种方式
aDivs = [...aDivs]; //将伪数组转换成真正的数组
//第二种方式
aDivs = Array.from(aDivs); //将伪数组转换成真正的数组
aDivs.forEach(function (item) {
console.log(item);
})
console.log(Array.of(1, 2, 3)); //新增,将参数序列变成数组
console.log(Array.isArray([1])); //新增,判断参数是否是一个数组
模板字符串
var name = 'fang'
var age = 23
const str = `My name is ${
`我的名字是 ${
name}`},My age is ${
age}`
console.log(str)
优点:支持换行,特定语法插入变量,特定语法插入表达式,使用${ }包裹变量和表达式,特殊符号原文输出需使用反斜杠转义。
Set和Map
我们学过的数据类型有对象和数组,ES6中新增了Set和Map两种类型的数据结构,这里我们做了解,不需要掌握,因为基本很少用到。
Set结构
一种新的数据结构,类似于数组
var set = new Set([1,2,3,4,4]); //构造函数,值不重复
我们可以利用Set结构里值不重复的特性,来完成数组的去重,代码如下
var arr = [11, 1, 1, 2, 2, 1, 3];
let set = new Set(arr);
console.log(set); //{11, 1, 2, 3}
arr = [...set]; //利用rest将伪数组转化为真正的数组
console.log(arr); // [11,1,2,3]
对于Set结构的数据操作
-
for of 是ES6新增遍历方式,可以遍历Set、数组、Map,但是不能遍历对象,因为对象类型没有实现iIerator接口,所以遍历对象时,仍然推荐使用for in遍历
for (let i of set) { console.log(i); //i表示set里的值 }
-
set.size //长度
-
set.add(0) //在末尾添加 0
-
set.delete(0) //删除 0
-
set.has(0) //判断是否有 0
-
set.clear(); //清空
-
keys():返回键名的遍历器,for (let item of set.keys()) { console.log(item); }
-
values():返回键值的遍历
-
entries():返回键值对的遍历器
-
forEach():使用回调函数遍历每个成员set.forEach((value, key) => console.log(value*2) )
Map结构
一种新的数据结构,类似对象
var map = new Map([["name","john"],["age",30]]);
参数是一个二维数组,我们一般用Map结构存储更复杂的数据,代码如下:
let obj1 = {
a: 1
};
let obj2 = {
b: 2
};
let obj = {
};
obj[obj1] = obj2;
console.log(obj);
我们从上面的代码发现,我们此时想用obj1指向的值做为键时,这个键会隐式的转换为 [Object object]的字符串,这不是我们想要的结果。要写成如下代码才行
let map = new Map([
[obj1, obj2]
]);
console.log(map);
对于Map结构的数据操作
- for of 遍历
- map.size //长度
- map.set(key,value);
- map.get(key);
- map.delete(key);
- map.has(key);
- map.clear();
- keys():返回键名的遍历器
- values():返回键值的遍历器
- entries():返回键值对的遍历器for (let [key, value] of map.entries()) { console.log(key, value); }
- forEach():使用回调函数遍历每个成员map.forEach((value, key) => console.log(value * 2) )
箭头函数
参数的情况
1、没有形参,()不可省略
let fun1 = () => console.log('fun1')
2、一个形参,()可省略
let fun2 = x => x
3、形参是两个或两个以上,()不可省略
let fun3 = (x,y) => x+y
函数的情况
1、函数只有一条语句或者表达式的时候,{}可以省略---------->会自动返回语句执行的结果或表达式的结果
let fun4 = (x,y) => x+y
2、函数体不止一条语句或者表达式的情况,{}不可省略
let fun5 = (x,y) => {
console.log(x,y)
return x+y
}
this指向问题
箭头函数没有自己的this,箭头函数的this不是调用的时候决定的,而是在定义的时候处在的对象就是它的this
扩展理解:箭头函数的this看外层是否有函数,如果有,外层函数的this就是内部箭头函数的this,如果没有则this就是window
案例一
btn.onclick = function(){
var foo = () => {
console.log(this); } //btn
foo();
}
案例二
var name = "window";
var obj = {
name: "obj",
fn: function () {
console.log(this.name);
return () => {
console.log(this.name);
}
}
};
obj.fn()();
案例三
var obj={
name:"箭头函数",
getName:() => {
btn.onclick = () => console.log(this);
}
}
btn.onclick = () => {
console.log(this); //window
}
obj.getName(); //window
Symbol
symbol 介绍
- 是ES6新增的一种基本数据类型
- symbol类型值是唯一的(利用这个特性可以做到对象属性名不重复)
- ES6之前有6种数据类型,5个基本数据类型:string number boolean null ndefined,1个引用数据类型object。加上ES6新增的基本数据类型symbol,就有7种数据类型。
symbol类型数据的创建
let a = Symbol();
let b = Symbol();
console.log(a == b); //false
symbol的运用
//symbol 新增的一种基本数据类型 symbol类型值是唯一的
let a = Symbol();
let b = Symbol();
console.log(a == b); //false
var obj = {
a: 1,
[a]: 11, //把symbol类型的值当成对象属性名的一种写法,一定要加[]
[b]: 2
}
console.log(obj);
console.log(obj[a], obj.a, obj["a"]); //11 1 1
for(let i in obj){
console.log(obj[i]); //1 只输出了一个1
}
symbal类型的数据是不能被遍历的,只能通过obj[a]的方式访问
Class
关键字class,用来创建类,这种创建方式是ES5中通过构造函数创建方式的一种“语法糖”,这种写法比较让人接受,或者说代码可读性更强,但本质上没有区别
class Person {
constructor(name,age){
//这个对应着ES5里的构造函数
this.name = name;
this.age = age;
}
sayHello() {
//原型方法
console.log(this.name);
}
}