// ES6允许按照一定模式 从数组和对象中提取值 对变量进行赋值 这就是解构
let [a,b,c] = [1,2,3]//模式匹配
let [foo,[[bar],baz]] = [1,[[2],3]]
foo//1
bar//2
baz//3
let [head,...tail] = [1,2,3,4];
head//1
tail//[2,3,4]
let [x,y,...z] = ['a'];
x//'a'
y//undefined 说明解构不成功 值为undefinded
z//[]
// 不完全解构模式 即等号左边的模式 只匹配部分等号右边的数组 即不完全解构
let [x,y] = [1,2,3]
x//1
y//2
// Set结构 也可使用数组的解构赋值
let[x,y,z] = new Set(['a','b','c'])
x//'a'
// 解构赋值允许指定默认指
let [foo = true] = []
foo//true
let [x,y = 'b'] = ['a']
x//'a'
y//'b'
const [a,x,c,s,a] = 'hello';//字符串的解构赋值 是将字符串转换成类似数组的对象
a//h
x//e
c//l
// 类似数组的对象都有一个length属性 所以还可以对这个属性解构赋值
// const声明一个只读常量 一旦声明 常量的值便不能改变
//因为const 声明变量不能改变 则必须一开始声明时就应该赋值 和var 不一样 否则会报错
//const 作用域与let相同 只在 声明所在的块级作用域有效 声明的变量也不提升 同样存在暂时性死区
//const 本质上保证的不是变量的值不得改动 而是变量指向的那个内存地址所保存的数据不得改动
// 对于复合型数据 变量指向的内存地址 保存的只是一个指向实际数据的指针 const 只能保证
// 这个指针是固定的(即总是固定指向一个地址)
const foo = {}
foo.prop = 123;
console.log(foo.prop);
// foo = {}//报错 因为常量foo储存的是一个地址 这个地址指向一个对象 不可变的是这个地址 即不能把这个地址指向
// 指向另一个地址 但对象本身是可变的数据结构 所以可以添加属性
const a=[];
a.push('hello')
a.length = 0;
// a = ['dave']//报错 同上 改变了数组
console.log(a);
const fooo = Object.freeze({});//冻结对象
fooo.prop = 123; //严格模式下可能会报错 一般模式新添加属性不起作用
// 将对象彻底冻结的函数
var constan = (obj) => {
Object.freeze(obj);
Object.keys(obj).forEach((key,i)=>{
if(typeof obj[key] == 'object'){
constan(obj[key])
}
})
}
// ES5只有两种声明变量的方法
// 1.var 命令
// 2.function命令
// ES6声明变量的方法:
// 1.var
// 2.let
// 3.const
// 4.class
// 5.function命令
// 6.import命令
// 顶层对象的属性
// 浏览器环境中 指window对象
// Node中指 global对象
// ES6中 var function 声明的全局变量依旧属于顶层对象的属性 (为和ES5兼容)
// 但let const class 声明的全局变量不再属于顶层对象的属性
// globalThis对象
// 浏览器里 顶层对象是window self也指向顶层对象
// node里 顶层对象是global