es6总结一
es6基础
let和const命令
let和const用于声明变量
let跟var的区别
1、let定义过的变量不能再定义,var定义过的变量可以重新定义
var name = 'tom';
var name = 'tony';
console.log(name); //输出tony
let name = 'tom';
let name = 'tony';
console.log(name); //报错 Identifier 'name' has already been declared name已经被声明
2、let定义的变量不会声明提升,var声明的变量会发生声明提升
console.log(age); //输出undefined var age会提升到console之前声明 但不会赋值
var age = 18;
console.log(age); //报错 age is not defined
let age = 18;
3、let定义的变量在let命令所在的代码块有效,var定义的变量在函数范围内有效
{
var age = 18;
let age1 = 19
}
console.log(age); //18
console.log(age1); //age1 is not defined
在{}里面 这是一个代码块 var的范围是在函数里面
注:<script></script>里面的代码会默认在最外层加载一个function
let的范围是在代码块
经典案例
function box(){
var arr = [];
for(var i=0;i<5;i++){
arr[i] = function (){
return i
};
}
return arr;
}
console.log(box()[0]()) //输出5
为什么会输出5呢?
这是一个经典的闭包,闭包是指有权访问另一个函数作用域中的变量的函数
在for循环里面的匿名函数执行 return i 语句的时候,由于匿名函数里面没有i这个变量,所以这个i他要从父级函数中寻找i,而父级函数中的i在for循环中,当找到这个i的时候,是for循环完毕的i,也就是5,所以这个box得到的是一个数组[5,5,5,5,5]。
解决方法
自执行函数
(function (){})()
通过给匿名函数传参,而传递的这个参数i是每次执行for循环里面的i,每次传递的参数i的值都不一样,匿名函数里面的num接收传递的参数i,所以box()最终输出结果为[0,1,2,3,4]
function box(){
var arr = [];
for(var i=0;i<5;i++){
arr[i] = (function (num){
return num
})(i);
}
return arr;
}
console.log(box()[0]) //输出0
使用es6 let
使用es6 let的特性 let定义的变量在let命令所在的代码块有效
function box(){
var arr = [];
for(let i=0;i<5;i++){
arr[i] = function (){
return i
};
}
return arr;
}
console.log(box()0) //输出0
const
一旦定义就不能修改
const a = 'aaa';
a = 'bbb'; //这时候会报错 Assignment to constant variable
当 const声明的变量为复杂数据类型时,可以改变里面的值
const obj = {
name:'张三',
age:18
}
obj.name = '李四';
console.log(obj) //这时候obj里面name的值变为李四了
是因为复杂数据类型是在堆内存中存储的,栈内存中只存放地址。基础数据类型是在栈内存中存储的,所有声明const a= 'aaa' 不能改变。而变量obj在栈内存中存放的是一个地址,堆内存中对象的值变了,并不影响栈内存的地址。所以obj的值变了,且不报错
数组结构解析
作用:从对象或者数组中取值,然后对变量进行赋值
数组的结构解析:按照对应的位置,把等号右边的数组中的值给等号左边的变量。数组可以嵌套
注意点:1、如果解析不成功,变量的值为undefined。2、等号右边不是数组会报错
let [a,b,c] = [1,2,3];
console.log(a,b,c); // 输出1,2,3
let [a,b,c] = [1,2];
console.log(a,b,c); //输出 1,2,undefined
let [a,b,c = 4] = [1,2];
console.log(a,b,c); //输出 1,2,4
let [a,b,c = 4] = [1,2,5];
console.log(a,b,c); //输出 1,2,5
let [a,b,c] =11;
console.log(a,b,c); //报错
对象的结构解析
let {name:name,age:age} = {name:'张三',age:18};
console.log(name,age); //输出张三 18
//可简写为
let {name,age} = {name:'张三',age:18};
console.log(name,age); //输出张三 18
模板字符串
`字符串${js表达式}`
扩展运算符
扩展运算符 ...
数组的扩展运算
数组的扩展运算就是将一个数组转换为用逗号分割的参数列表
用于数组的解析
let arr = [11,22,33,44];
console.log(...arr); // 解析为11,22,33,44
用于方法的参数
情景一
function show (n1,n2,n3){
console.log(n1,n2,n3)
}
let arr = [11,22,33]
show(...arr)
情景二
function sum (...arr){ //也可以用arguments
let result = 0;
for(let i = 0;i<arr.length;i++){
result +=arr[i];
}
}
sun(...[11,22,33,44])
扩展运算符拷贝的数组属于深copy
同样属于深copy的还有array.concat(); array.slice()
数组的扩展运算
let obj1 = {name:'tom',age:'18',friend:{name:'张三',age:18}}
let obj2 = {...obj1}
obj2.name='王麻子'
console.log(obj1,obj2); //{name: "tom", age: "18", friend: {name:'张三',age:18}} {name: "王麻子", age: "18", friend: {name:'张三',age:18}}
你会发现obj2的name值变了 obj1的没变。
let obj1 = {name:'tom',age:'18',friend:{name:'张三',age:18}}
let obj2 = {...obj1}
obj2.name='王麻子'
obj2.friend.name='张麻子'
console.log(obj1,obj2); //{name: "tom", age: "18", friend: {name:'张麻子',age:18}} {name: "王麻子", age: "18", friend: {name:'张麻子',age:18}}
你会发现obj1.friend,obj2.friend的name值都变了 所以数组的扩展运算拷贝对象不是深拷贝