let 与 const
- 特点:
没有变量提升
:一定要先声明后使用有块级作用域
:只要是大括号里声明的变量,都是局部的
// 1.ES5声明变量var特点
//1.1 有变量提升
//var num; 编译器会将var声明提升到当前作用域最顶端
console.log(num);//undefined
var num = 10;
//1.2 没有块级作用域 (块级作用域: 大括号里面的变量都是局部的)
if(1){
//var在大括号里面声明的还是全局的
var num = 20;
};
console.log( num );//20
// 2.ES6声明变量let与const特点
// 2.1 没有变量提升
console.log(num);//报错: Cannot access 'num' before initialization
let num = 10;
//2.2 有块级作用域
if(1){
let num = 20;
console.log(num);
};
console.log(num);//num is not defined
- let 与 const区别
- let :
变量
。可以重新赋值 - const:
常量
。不可以重新赋值,只能在声明的时候唯一赋值一次
- let :
//3.1 let : 变量(可以重新赋值)。 和var一样的
let a = 10;
console.log(a);//10
a = 100;
console.log(a);//100
// //3.2 const : 常量(不可以重新赋值)。 只能声明的时候赋值一次
const b = 800;
console.log(b);//800
b=400;
console.log(b);//报错 TypeError: Assignment to constant variable.
对象的解构赋值
变量赋值的简写形式
- 取出对象的值赋给变量
//1.ES5写法
// let obj = {
// name : '张三',
// age:20,
// sex:'男'
// };
// let name = obj.name;
// let age = obj.age;
// let sex = obj.sex;
// console.log(name,age,sex);//张三 20 男
//2 ES6解构赋值
let obj = {
name : '张三',
age:20,
sex:'男'
};
// let age = obj.age;
// let name = obj.name;
// let gender = obj.sex;
// 以上为原理
let {age,sex:gender,name} = obj;//相当于在全局变量中声明里age,gender,name
console.log(name,age,gender);//张三 20 男
console.log(sex);//报错 sex is not defined sex变量未声明
- 取出变量的值 赋值给 对象
//ES5 写法
let obj = {
name:name,
age:age,
sex:sex
};
console.log(obj);//{ name: '李四', age: 22, sex: '女' }
//ES6 写法
let obj1 = {
name,//等价于 name:name
age,
sex,
sayHi:function(){ console.log(111) },
eat(){// 等价于 eat:function(){}
console.log(2222);
}
};
console.log(obj1);
/* 运行结果:{
name: '李四',
age: 22,
sex: '女',
sayHi: [Function: sayHi],
eat: [Function: eat]
} */
- 解构赋值语法默认值
let obj = {
name:'王五',
sex:'男',
age:0
};
// let name = obj.name;
// let sex = obj.sex;
/*
(1)声明变量 let age;
(2)检查obj有没有属性要age,有则赋值。 没有则赋默认值
if( obj.age != undefined ){ age = obj.age }else{ age = 18 }
*/
let {name,sex,age = 18} = obj;
console.log(name,sex,age);//王五 男 0
数组的解构赋值
/* 数组解构赋值 */
let arr = [10,20,30];
/* 解构数组 */
// let n1 = arr[0]
// let n2 = arr[1]
// let n3 = arr[2]
// let n4 = arr[3]
//以上是原理
let [n1,n2,n3,n4=100] = arr;
console.log(n1,n2,n3,n4);//10 20 30 100,如果n4不赋值100则返回undefined
函数解构与函数默认参数
函数传参的本质:实参给形参赋值
ES5接收参数: let obj = {name:'张三',age:20}
ES6接收参数: let {name,age,sex="男"} = {name:'张三',age:20}
// ES5
function fn(obj){//let obj={name:'张三',age:18}
console.log(obj);//{ name: '张三', age: '18' }
// 取出
let name = obj.name;
let age = obj.age;
console.log(name,age);
}
fn({name:'张三',age:'18'});//张三 18
// ES6
function fn({name,age,sex="男"}){//let {name,age} = {name:'张三',age:18}
console.log(name,age);
}
fn({name:'张三',age:'18'});//张三 18
- 函数默认参数
//2.函数默认参数
function fn1(a = 10 ,b = 20){
//ES5 : 逻辑或短路
// a = a || 10;
// b = b || 20;
console.log(a,b);
};
fn1(100,200);//100 200
fn1();//10 20
fn1(5);//5 10
箭头函数
- 就是function函数的简写形式
- (1)将function替换成箭头
=>
- (2)将形参小括号移到箭头=>的左边
- let fn = ()=>{}
- (1)将function替换成箭头
- a.如果函数只有一个形参,则可以省略形参小括号
- b.如果函数体只有一行,则可以省略函数体大括号(
此时必须要省略return
) - 特点
- 简洁
箭头函数没有自己的this,箭头函数的this不是调用的时候决定的,而是在定义的时候所处在的对象就是它的this
拓展理解:
箭头函数的this看最外层是否有函数,如果有,外层函数的this就是内部箭头函数的this,如果没有,则this是window
//无参无返回
let fn = ()=>{
console.log('666');
};
fn();
//有参有返回
let fn1 = (a,b)=>{
return a + b;
};
let res = fn1(10,20);
console.log(res);//30
//2.其他用法
//2.1 如果函数只有一个形参,则可以省略形参小括号
let fn2 = a=>{ return a*2 };
let res2 = fn2(100);
console.log(res2);//200
//2.2 如果函数体只有一行代码,则可以省略大括号(此时也必须要省略return)
let fn3 = a =>a*2;
let res3 = fn3(500);
console.log(res3);//1000
- 特点
<body>
<button id="btn1">测试this1</button>
<button id="btn2">测试this2</button>
<script>
// 测试箭头函数this
let btn1 = document.getElementById('btn1');
let btn2 = document.getElementById('btn2');
// 普通回调函数
btn1.onclick = function () {
console.log(this); //<button id="btn1">测试this1</button>
};
// 箭头函数
// btn2.onclick = () => {
// console.log(this); //window
// };
let obj = {
name: '箭头函数',
getName() {//getName:funtion() 常规函数
btn2.onclick = () => {
console.log(this);//指向{name: "箭头函数", getName: ƒ}
};
},
};
obj.getName();
let obj = {
name: '箭头函数',
getName:() => {
btn2.onclick = () => {
console.log(this);//{name: "箭头函数", getName: ƒ}
};
},
};
obj.getName();//指向window
</script>
</body>
当btn2的点击事件外层是常规函数,看的就是常规函数的指向,所以是obj。
当btn2的点击事件外层是箭头函数,看起外层箭头函数的指向,外层箭头函数没有外层函数所以指向window。
模板字符串
- ES5的字符串特点: 一切以单引号’’ 或 双引号
""
引起来的内容
1.1 不能字符串里面取变量的值 : 需要使用连接符+
1.2 不能识别字符串格式 : 需要使用转义符
- ES6新增 模板字符串: 一切以反引号引起来的内容 ``
1.1 可以取变量的值: ${变量名}
1.2 可以识别字符串格式
let name = '张三';
let str1 = '我是\n'+name;
console.log(str1);
// 2.ES6新增 模板字符串:一切以反引号引起来的内容
// 2.1可以取变量的值:${变量名}
// 2.2可以支持字符串格式
let name2 ='李四';
let str2 = `我是
${name2}`;
console.log(str2);
拓展运算符(…)
作用:遍历对象一种简写形式(类似for-in循环)
let car = {
pinpai: '劳斯莱斯幻影',
price: 1000000000,
};
let house = {
address: '深圳湾一号',
};
let person = {
name: '陆离',
age: 30,
...car,
...house,
};
console.log(person);
应用场景
- 连接数组
let arr1 = [10, 20, 30];
let arr2 = [40, 50, 60];
// ES5:concat
let arr3 = arr1.concat(arr2);//连接arr1和arr2
arr3.push(80,90,100);//连接之后继续添加元素
console.log(arr3);//[10, 20, 30, 40, 50,60, 80, 90, 100]
// ES6展开运算符
let arr4 = [...arr1, ...arr2, 80, 90, 100];
console.log(arr4);//[10, 20, 30, 40, 50,60, 80, 90, 100]
- 求数组最大值/最小值
// 2.2求数组最大值/最最小值
let arr = [88,100,20,50,60];
//ES5:擂台思想、Math.max.apply()
// let max = Math.max.apply(Math,arr);
// console.log(max);//100
//ES6展开运算符
let max =Math.max(...arr);
console.log(max);//100
数据类型Set
集合:与数组几乎一致,唯一的区别是不支持重复元素(相当于是无法储存重复元素的数组)
- set 一般不会单独使用,只是为了去掉数组重复的元素。将set转成数组
// 声明Set:new Set(数组)
let set = new Set([10, 20, 30, 66, 30, 100, 50, 90, 100]);
console.log(set); //{ 10, 20, 30, 66, 100, 50, 90 }
// set 一般不会单独使用,只是为了去掉数组重复的元素。将set转成数组
let arr = [...set];
console.log(arr);//[10, 20, 30, 66,100, 50, 90]
- 数组去重
let arr1 = [88, 20, 66, 20, 30, 88, 100, 50];
// 最简单的一行代码实现数组去重
let newArr = [...new Set(arr1)];
console.log(newArr);//[ 88, 20, 66, 30, 100, 50 ]