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');
    };
  • 相关阅读:
    Largest Rectangle in Histogram
    Valid Sudoku
    Set Matrix Zeroes
    Unique Paths
    Binary Tree Level Order Traversal II
    Binary Tree Level Order Traversal
    Path Sum II
    Path Sum
    Validate Binary Search Tree
    新手程序员 e
  • 原文地址:https://www.cnblogs.com/tengx/p/8862749.html
Copyright © 2011-2022 走看看