博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
[js高手之路] es6系列教程 - var, let, const详解
阅读量:6581 次
发布时间:2019-06-24

本文共 4599 字,大约阅读时间需要 15 分钟。

1         function show( flag ){ 2             console.log( a ); 3             if( flag ){ 4                 var a = 'ghostwu'; 5                 return a; 6             } else { 7                 console.log( a ); 8                 return null; 9             }10         }

我们从es5的开始说起, 由于变量提升的原因, 上述程序, 在第2行和第7行都能访问到a的值, 只不过是undefined, 如果你不熟悉javascript这种变量的预解释机制,可能会认为第2行和第7行会报错, 只有flag为true的时候,变量a才声明了, 其实javascript在词法解释的时候,会把上述代码解释成下面的样子:

1        function show( flag ){ 2             var a; 3             console.log( a ); 4             if( flag ){ 5                 a = 'ghostwu'; 6                 return a; 7             } else { 8                 console.log( a ); 9                 return null;10             }11         }

这种机制,在项目中经常误导程序员,哪怕是资深的前端程序员,不小心也容易入坑, 于是ES6引入了块级作用域来强化对变量生命周期的控制.

什么是块级作用域?

1,函数内部

2,块中( 通常指的是一对花括号之间)

es6中使用新的关键词 let 来定义变量, 为块级作用域,上例,如果改成let声明

1     function show( flag ){ 2             console.log( a ); 3             if( flag ){ 4                 let a = 'ghostwu'; 5                 return a; 6             }else { 7                 console.log( a ); 8                 return nul; 9             }10         }

由于let是块级作用域,不会像var一样 产生变量提升, 所以,第2行和第7行 这个时候报错( a is not defined )

只有在flag为true的情况,a会被定义, 而且访问范围在第3行和第6行的大括号之间, 超出这个范围,就访问不到a, 这就是块级作用域

let都有哪些特性呢?

在同一个作用域下,let不能重复定义两个同名的标识符

在不同的作用域下,可以使用同名的标识符

1 var a = 'ghostwu';2 let a = 'ghostwu2';
1 let a = 'ghostwu';2 let a = 'ghostwu2';

以上两种方式,都会报重定义错误(Identifier 'a' has already been declared)

1         let a = 10;2         if( a ){3             let a = 100;4             console.log( a ); //1005         }6         console.log( a ); //10

以上这种方式,不会报错,因为是两个不同的作用域

let的经典应用

在4个按钮中,获取当前被点击按钮的索引

1      11 12    13     14     15     

如果,我们用上面的方法做, 每个按钮点击之后 i 都是4, 因为4个按钮绑定完事件之后,i的值就变成了4, 下次点击按钮的时候,所有的都是4, 因为 i = 4 是共享的

通常,我们会在每个按钮上,加一个自定义索引 绑定 对应的 i 值,再借助this关键字,就可以如愿以偿,如下:

1         window.onload = function(){2             var aInput = document.querySelectorAll("input");3             for( var i = 0; i < aInput.length; i++ ){4                 aInput[i].index = i;5                 aInput[i].onclick = function(){6                     alert(this.index);7                 }8             }9         }

还有另一种方法,就是借用立即表达式+闭包的形式, 如下:

1         window.onload = function(){ 2             var aInput = document.querySelectorAll("input"); 3             for( var i = 0; i < aInput.length; i++ ){ 4                 aInput[i].onclick = (function( j ){ 5                     return function(){ 6                         alert( j ); 7                     } 8                 })( i ); 9             }10         }

而采用let关键字, 利用块级作用域的特性,就可以轻松达到目的

1         window.onload = function(){2             var aInput = document.querySelectorAll("input");3             for( let i = 0; i < aInput.length; i++ ){4                 aInput[i].onclick = function(){5                     alert( i );6                 };7             }8         }

 

var在全局作用域下,会把属性绑定到window上,从而可能产生覆盖属性的隐患,而let关键字只是会遮蔽它,并不会覆盖window上的同名属性

1         var a = 10; 2         console.log( a );  //10 3         console.log( window.a ); //10 4         console.log( 'a' in window ); //true 5  6         let user = 'ghostwu'; 7         console.log( user ); //ghostwu 8         console.log( window.user ); //undefined 9         console.log( 'b' in window  ); //false10 11 12         /*13         var RegExp = 'ghostwu';14         console.log( RegExp );  //ghostwu15         console.log( window.RegExp ); //ghostwu16         console.log( 'RegExp' in window ); //true17         */18 19         let RegExp = 'ghostwu';20         console.log( RegExp );  //ghostwu21         console.log( window.RegExp ); //function RegExp() { [native code] }22         console.log( 'RegExp' in window ); //true

const关键字是用来定义常量的,它有如下特性:

.块级作用域

.声明的时候,必须赋予初始值

.不能被重新赋值

.如果值是一个对象, 那么对象里面的属性是允许被修改的

.不能跟其他标识符重名

1         const user = 'ghostwu';2         console.log( user );3         user = 'zhangsan'; //报错, 不能重新赋值
1 const user; //报错,定义的时候 没有给初始值
1         const user = {2             name  : 'ghostwu'3         };4         console.log( user.name ); //ghostwu5         user.name = 'zhangsan';  //对象的属性允许被修改6         console.log( user.name ); //zhangsan
1        const user = {2             name  : 'ghostwu'3         };4         user = {    //报错,不能重新给user赋值5             name : 'zhangsan'6         }7         console.log( user.name ); //报错
1         var a = 10;2         const a = 10; // 报错,重定义错误
1         let a = 10;2         const a = 10; //报错,重定义错误
1        if ( true ) {2             const a = 10;3             console.log( a ); //104         }5         console.log( a ); //报错:a is not defined

 

转载地址:http://klnno.baihongyu.com/

你可能感兴趣的文章
使用WMI来连接远端计算机
查看>>
Linux下的线程
查看>>
Fat-jar 打包,并使用 proguard 混淆代码
查看>>
[转]jquery.pagination.js分页
查看>>
C#泛类型链表的实现
查看>>
升级到WP8必需知道的13个特性
查看>>
Ext.getCmp()的简单使用
查看>>
前端样板资源概览及总评
查看>>
atitit.常用编程语言的性能比较 c c++ java
查看>>
[开发笔记]-实现winform半透明毛玻璃效果
查看>>
一款非常棒的纯CSS3 3D菜单演示及制作教程
查看>>
CSS3+HTML5特效8 - 顶部和右侧固定,左侧随窗口变化的布局
查看>>
利用c#+jquery+echarts生成统计报表(附源代码)
查看>>
簡單SQL存儲過程實例
查看>>
于西蔓_百度百科
查看>>
AMD and CMD are dead之KMD.js依赖可视化工具发布
查看>>
网页刷新方法集合
查看>>
[Android]对BaseAdapter中ViewHolder编写简化(转)
查看>>
java画图程序_图片用字母画出来_源码发布_版本二
查看>>
[Node.js]23. Level 4: Semantic versioning
查看>>