zoukankan      html  css  js  c++  java
  • [js高手之路] es6系列教程

     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 ); //100
    5         }
    6         console.log( a ); //10    

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

    let的经典应用

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

     1      <script>
     2         window.onload = function(){
     3             var aInput = document.querySelectorAll("input");
     4             for( var i = 0; i < aInput.length; i++ ){
     5                 aInput[i].onclick = function(){
     6                     alert( i );
     7                 }
     8             }
     9         }
    10     </script>
    11 
    12    <input type="button" value="按钮1">
    13     <input type="button" value="按钮2">
    14     <input type="button" value="按钮3">
    15     <input type="button" value="按钮4">

    如果,我们用上面的方法做, 每个按钮点击之后 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  ); //false
    10 
    11 
    12         /*
    13         var RegExp = 'ghostwu';
    14         console.log( RegExp );  //ghostwu
    15         console.log( window.RegExp ); //ghostwu
    16         console.log( 'RegExp' in window ); //true
    17         */
    18 
    19         let RegExp = 'ghostwu';
    20         console.log( RegExp );  //ghostwu
    21         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 ); //ghostwu
    5         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 ); //10
    4         }
    5         console.log( a ); //报错:a is not defined
  • 相关阅读:
    VMware提示此主机支持Intel VT-x,但Intel VT-x处于禁用状态怎么解决
    linux中几种安装软件 方法
    Linux向文件添加内容的几种方法
    什么是模块?模块划分的原则是什么?
    NOIP2009 t3 最优贸易
    HDU3072 Intelligence System
    洛谷P2569 股票交易
    玄学
    [0403]学习一个——苟(简单Java开发)
    实验 3:类和对象
  • 原文地址:https://www.cnblogs.com/ghostwu/p/7286053.html
Copyright © 2011-2022 走看看