zoukankan      html  css  js  c++  java
  • ES6入门详解(一) let const

    在es6之前 JS实际上并没有块级作用域的概念 只有词法作用域 在es6中的let 与 const 就实现了块级作用域 和天然的模块化 var标签直接挂载到全局对象的特性无法实行模块化

    let  用于for循环 let支持块级作用域 所以每次循环都是一个 单独的作用域 而重新定义循环变量 JavaScript 引擎内部会记住上一轮循环的值,初始化本轮的变量i时,就在上一轮循环的基础上进行计算。另外,for循环还有一个特别之处,就是设置循环变量的那部分是一个父作用域,而循环体内部是一个单独的子作用域。

    let命令不存在变量声明提升

    let 与 const 命令会形成暂时性死区

    let temp = '234'
    if(true){
        console.log(temp)
        let temp = '123'
    }

    上面代码就是暂时性死区的运行 如果在块级作用域内 已经存在了 let const 声明的变量 那么 在这之前的范围都属于死区范围 同样 typeof 在判断未声明的变量时 会返回undefined但是在判断暂时性死区的变量就会抛出引用错误 所以在这里还是遵守规范变量先声明再使用

    在定义函数时也会出现暂时性死区的概念

    function fn(x = y , y = 2) {
        return x + y
    }
    fn()

    这个时候因为y 还没有执行到 所以这时候引用Y 就会报错 如果用下面方式运行就不会报错了

    function fn1(x = 2 , y = x){
        return x+y
    }
    console.log(fn1())

    因为var的 变量声明提升机制 所以 var x = x 这是可以被执行的 结果是 undefined 但是let 并不会存在变量声明提升 let x = x 就是引用了一个不存在的变量会报错

    所以暂时性死区就是说 当程序一执行到当前作用域 变量就已经存在 但是不能引用 只有在变量声明之后才可以调用 

    无论是const 还是let 都不允许 在同一作用域下 重复声明 

    const x = 2
    const x = 2

    下面来说一下块级作用域下的函数声明 这是个大坑 在es6标准中 块级作用域的funcion 声明类似于let 在块级作用域外不能被访问但实际是可以的

    if(true){
        function fn(){
            console.log(111)
        }
    }else{
        function fn2(){
            console.log(2222)
        }
    }
    console.log(fn)
    console.log(fn2)

    首先上述代码的执行按照标准应该报错 但实际是可以的 

    好这里也就是说 在node 与 浏览器环境下 块级作用域内声明的函数 依然可以被外部 引用  并且 类似var 首先js会预处理所有的function声明 将其提升到当前词法作用域顶部 值为undefined 因为这种声明不可控性 太高而且巨坑 所以尽可能使用 函数表达式声明函数

    最后说一下const const声明的是常量

    const实际上保证的,并不是变量的值不得改动,而是变量指向的那个内存地址不得改动。对于简单类型的数据(数值、字符串、布尔值),值就保存在变量指向的那个内存地址,因此等同于常量。但对于复合类型的数据(主要是对象和数组),变量指向的内存地址,保存的只是一个指针,const只能保证这个指针是固定的,至于它指向的数据结构是不是可变的,就完全不能控制了。因此,将一个对象声明为常量必须非常小心。

    因为这种特性所以如果真的想彻底冻结对象需要使用 Object.freeze

    const foo = Object.freeze({});

    如果想要冻结对象的所有属性 可以通过递归的形式来完成

    let congelation = obj => {
        Object.freeze(obj);
        //枚举对象所有的属性
        Object.keys(obj).forEach((key , i ) => {
            if(typeof obj[key] === 'object'){
                congelation(obj[key])
            }
        })
    }
    
    let obj = {
        a : {},
        b:{},
        c:2
    }
    
    congelation(obj)
    obj.ss = {}
    
    console.log(obj)
     

    同一段代码为了能够在各种环境,都能取到顶层对象,现在一般是使用this变量,但是有局限性。

    全局环境中,this会返回顶层对象。但是,Node 模块和 ES6 模块中,this返回的是当前模块。函数里面的this,如果函数不是作为对象的方法运行,而是单纯作为函数运行,this会指向顶层对象。但是,严格模式下,这时this会返回undefined。不管是严格模式,还是普通模式,new Function('return this')(),总是会返回全局对象。但是,如果浏览器用了 CSP(Content Security Policy,内容安全政策),那么evalnew Function这些方法都可能无法使用。

    如果想要在所有环境都拿到全局对象有几个方法

    // 方法一
    (typeof window !== 'undefined'
        ? window
        : (typeof process === 'object' &&
            typeof require === 'function' &&
            typeof global === 'object')
            ? global
            : this);
    
    // 方法二
    var getGlobal = function () {
        if (typeof self !== 'undefined') { return self; }
        if (typeof window !== 'undefined') { return window; }
        if (typeof global !== 'undefined') { return global; }
        throw new Error('unable to locate global object');
    };
  • 相关阅读:
    Struts2升级注意事项
    使用HttpClient获取网页源码
    The method getJspApplicationContext(ServletContext) is undefined for the type JspFactory解决方案
    IBatis常见错误集锦
    JPush极光推送Java服务器端API
    JS去空trim
    Jquery常用操作
    适配器模式(Adapter)
    常见数据库设计(3)——历史数据问题之多记录变更
    VS2008 工具箱都是textbox(报表设计时)
  • 原文地址:https://www.cnblogs.com/tengx/p/8862749.html
Copyright © 2011-2022 走看看