《ES6标准入门(第3版)》学习笔记2:chapter_2 - 2 块级作用域

这是该系列的第2篇笔记!
让学习“上瘾”,成为更好的自己!!!

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>块级作用域</title>
</head>

<body>

    <script>
        /*
    ES5只有全局作用域和函数作用域,没有块级作用域
    
    */
        // 1,为什么需要块级作用域?
        // for one: 内层变量可能会覆盖外层变量
        // var tmp = new Date();
        // function f() {

        //     console.log(tmp);
        //     if (false) {
        //         var tmp = 'hello world';
        //     }
        // }
        // f();  // undefined --> why? 变量提升导致内层的temp变量覆盖了外层的tmp变量


        // for two: 用来计数的循坏变量泄漏为全局变量
        // var s = 'hello';
        // for (var i = 0; i < s.length; i++) {
        //     console.log(s[i]);

        // }
        // console.log(i); // 5 --> 变量i原本只用来控制循坏,但是循坏结束后,并没有消失,而是泄漏为全局变量


        // 2, ES6的块级作用域
        // (1) let实际上为JavaScript新增了块级作用域
        // function f1() {
        //     let n = 5;
        //     if (true) {
        //         let n = 10;
        //     }
        //     console.log(n);  // 5
        // }

        // f1();

        // (2)ES6允许块级作用域的任意嵌套
        // 外层作用域无法读取内层作用域的变量!
        // {{{{
        //     {let insane = 'hello world';}
        //     console.log(insane);  // error
        // }}}};
        
        // 内层作用域可以定义外层作用域的同名变量
        // {{{{
        //     let insane = 'hehfje';
        //     {let insane = 'hello world';}
        //     console.log(insane); 
        // }}}};


        // 立即执行匿名函数(IIFE)与块级作用域
        // IIFE
        // (function(){
        //     var temp = 2333;
        // }());
        // // 块级作用域写法
        // {
        //     let temp = 23243;
        // }


        // 3,块级作用域与函数声明
        // (1)ES5规定,函数只能在顶层作用域和函数作用域之中声明,不能在块级作用域中声明
        // case 1:
        // if(true){
        //     function(){

        //     }

        // }

        // case 2:
        // try {
        //     function f(){
        //         // 
        //     }
        // } catch(e){
        //     // 
        // }
        // 以上两种都是ES5中非法的写法,但浏览器为了兼容旧代码,这两种情况都可以运行 

        // (2) ES6引入块级作用域,明确规定在块级作用域中声明函数
        //  --> ES6规定,在块级作用域中,函数声明语句的行为类似于let,在块级作用域之外不可引用


        //  ES5中
        // function f(){
        //     console.log('i am outside!');
    
        // }

        // (function(){
        //     // function f(){console.log('i am inside!'); }  // 正常
        //     if (false){
        //         function f(){console.log('i am inside!'); }   // error

        //     }
        //     f();
        // }());


        // ES6中
        // 改变块级作用域内声明的函数的处理机制,会对旧代码产生影响
        // 为了减轻因此产生的不兼容问题:ES6规定:
        //      a, 允许在块级作用域内声明函数
        //      b, 函数声明类似var,即会提升至全局作用域或函数作用域的头部
        //      c, 同时,函数声明还会提升到所在块级作用域的头部
        //【注意】这3条规则只对ES6的浏览器的实现有效,其他环境下的实现不用遵守,仍旧将块级作用域的函数声明当作let处理即可

        // 浏览器ES6的环境  --> 以下的代码在ES6环境中都会报错
        // function f(){
        //     console.log('i am outside!');
    
        // }

        // (function(){
        //     if (false){
        //         f();
        //         function f(){console.log('i am inside!'); }   // error
                

        //     }
        //     f();  // Uncaught TypeError: f is not a function
        // }());

        // ES6中实际运行的代码为:
        // function f(){
        //     console.log('i am outside!');
    
        // }

        // (function(){
        //     var f ;  // 函数声明类似var,即会提升至全局作用域或函数作用域的头部
        //     if(false){
        //         function f(){ console.log('i am inside!!'); }
        //         f();  // 同时,函数声明还会提升到所在块级作用域的头部

        //     }
        //     f();
        // }());


        // 【注意】考虑到导致行为差异太大,应该避免在块级作用域内声明函数!!!
        //        如果确实需要,要写成函数表达式的形式,而不是函数声明的语句

        // 不报错写法(函数表达式)
        // function f(){
        //     console.log('i am outside!');
    
        // }

        // (function(){
        //     if(false){
        //        let f = function(){ console.log('i am inside!!'); }
               
        //     }
        //     f();
        // }());




        // 函数声明的语句
        // {
        //     let a = 'secret';
        //     function f() {
        //         return a;
        //     }
        // }


        //  ===等价于====

        // 函数表达式的语句

        // {
        //     let a = 'secret';
        //     let f = function() {
        //         return a;
        //     };
        // }

        // ES6的块级作用域允许声明函数的规则只在使用大括号的情况下成立,如果没有使用大括号,则会报错(严格模式下)

            // 不报错
            // 'use strict';
            // if(true){
            //     function f(){}

            // }

            //  // 报错
            //  'use strict';
            // if(true)
            //     function f(){}






        // 4,do表达式(只是提案!!)
        // 本质上,块级作用域是一个语句,将多个操作封装在一起,没有返回值
        // {
        //     let t = 32;
        //     t = t + 12;
        // }

        // 【改变】
        // 在块级作用域之前加上do,可以是块级作用域变成do表达式,即可以返回值
        // let x = do {
        //     let t = 32;
        //     t = t + 12;
        // };
        // console.log(x);
        



    // test 
    // 为了减轻因此产生的不兼容问题:ES6规定:
        //      a, 允许在块级作用域内声明函数
        //      b, 函数声明类似var,即会提升至全局作用域或函数作用域的头部
        //      c, 同时,函数声明还会提升到所在块级作用域的头部
    
    // 
    //     console.log(f);  // undefined
    //     // f();  // error
    //    if (true){
    //     function f(){ console.log('i am inside!');}
    //     f();  // 'i am inside!'
    //    }
    //    f();  // 'i am inside!'

        

    </script>





</body>

</html>
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值