20200616_『ES6』块级作用域,暂时性死区,let ,const,全局变量

	kiss keep it simple stupid

块级作用域

块作用域由 { } 包括,if语句和for语句里面的{ }也属于块作用域。
for()中也属于块级作用域,是{}的父级块作用域。

			for(let i=0;i<10;i++){
				let i=1;
				console.log(i);//1 1 1 1 1 1 1 1 1 1
			}
			console.log(i);//a is not  defined

暂时性死区:

	只要块级作用域内存在let命令,它所声明的变量就“绑定”(binding)这个区域,不再受外部的影响。
	在代码块内,使用let命令声明变量之前,该变量都是不可用的。这在语法上,称为“暂时性死区”(temporal dead zone,简称TDZ)。
			{
				//TDZ开始
				a=1;//
				console.log(a);//ReferenceError:Cannot access 'a' before initialization
				let a;//TDZ结束
				console.log(a);//ReferenceError:Cannot access 'a' before initialization
				a=123;
				console.log(a);//123
			}
			var x = 1; 
			{
				//存在暂时性死区(TDZ),当前作用域不能拿到上一层作用域中的x。在引用之前没有负值,报错。
				let x = x;
				console.log(x);
			}

let

	1、不能在同一作用域下重复声明;(Uncaught SyntaxError: Identifier 'a' has already been declared)
	2、使用let var 一起也不能在同一个作用域重复声明。
	3、用let定义变量时,也不能与形参同名。比如:
			function test(a){
				let a=0;
				console.log(a);//Uncaught SyntaxError: Identifier 'a' has already been declared(未捕获的语法错误:标识符a已经声明)
			}
			test();
			function test(a){
				{
					let a=0;
				}
				console.log(a);//undefined
			}
			test();
			
			function test(a){
				{
					let a=0;
					console.log(a);//10
				}
				console.log(a);//undefined
			}
			test();

4、let 不会变量提升,会产生一个暂时性死区。

5、let 只能在当前的块级作用域下生效。

			var arr=[];
			for(var i=0;i<10;i++){
				arr[i]=function(){
					console.log(i);
				}
			}
			for(var i=0;i<10;i++){
				arr[i]();
			}
			//0 1 2 3 4 5 6 7 8 9

不是因为坑多。。是因为技术不到家

			var i=0;
			for(;i<10;i++){
				var i='a';
				console.log(i);//a
			}
			for(let i=0;i<10;i++){
				i="a";
				console.log(i);//a 
			}
			for(let i=0;i<10;i++){
				var i="a";
				console.log(i);//Uncaught SyntaxError: Identifier 'i' has already been declared
			}
			for(let i=0;i<10;i++){
				let  i="a";
				console.log(i);//a a a a a a a a a a
			}
//------------------------------------------------
			var a=1;
			if(1){
				let a=3;
				{
					let a=10;
					console.log(a);//10
				}
				console.log(a);//3
			}
			console.log(a);//1
//------------------------------------------------
			var a=1;
			if(1){
				let a=3;
				{
					var a=10;
					console.log(a);//报错
				}
				console.log(a);
			}
			console.log(a);

块级作用域等于匿名函数的立即执行?

			for(var i=0;i<10;i++){
				var i='a';
				console.log(i);
			}
			var arr=[];
			for(let i=0;i<10;i++){
				arr[i]=function(){
					console.log(i);
				}
			}
			for(var k=0;k<10;k++){
				
				arr[k]();
			}

在同一个作用域下,不能声名let和function同名的变量和方法。报错

			{
				let a=1;
				function a(){}
				console.log(a);//报错 Uncaught SyntaxError: Identifier 'a' has already been declared
			},
			//---------------------------
			{
				let a=1;
				{
					a();
					//函数提升,只在函数的作用域内提升
					function a(){
						console.log(22);//22
					}
				}
				console.log(a);//1
			}

const

定义常量,不可变的量
1、声明就必须要赋值;
2、不可以变更值;
3、其它性质跟let一样。
4、如果常量是引用类型,可以修改里面的值;如果想冻结该引用类型的常量不可修改,可以使用Object.freeze();

//声明就必须要赋值;
const a;
console.log(a);//Uncaught SyntaxError: Missing initializer in const declaration(const声明中缺少初始化器)

//不可以变更值
const a=1;
a=2;
console.log(a);//Uncaught TypeError: Assignment to constant variable.(未捕获类型错误:对常量变量的赋值。)

不能重复定义

			const a=1;
			var a=2;//Uncaught SyntaxError: Identifier 'a' has already been declared
			let a=3;//Uncaught SyntaxError: Identifier 'a' has already been declared
			function a(){}//Uncaught SyntaxError: Identifier 'a' has already been declared

如果常量是引用类型,可以修改里面的值

			const obj={};
			obj.name='mymy'
			console.log(obj);//{name: "mymy"}

如果想冻结该引用类型的常量不可修改,可以使用Object.freeze();

			const obj={name:'yourself'};
			Object.freeze(obj);
			obj.name='mymy'
			console.log(obj);//{name: "yourself"}

全部的属性冰结

			function myFreeze(obj) {
				Object.freeze(obj);
				for (var key in obj) {
					if (typeof(obj[key]) === 'object' && obj[key] !== null) {
						Object.freeze(obj[key]);
						myFreeze(obj[key]);
					}
				}
			}
			const person = {
				son: {
					cai: 65,
					yi: 56,
					bi: {
						oi: 12,
						ui: 32
					}
				},
				house: ['www', 'ccc', 'eee']
			}
			myFreeze(person);
			person.son.bi.oi=100;
			console.log(person)

全局变量

使用let、const在最顶层定义变量和常量时,不会产生全局变量。不会直接挂在window上。

其它

不建议在块级作用域当中使用函数声明的方式来声明函数,而是应该用函数表达示的方式来声明。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值