ES6 (一) 变量声明

阅读: 评论:0

ES6 (一) 变量声明

ES6 (一) 变量声明

  • 1、 变量声明–let、coust
  • 2、 顶层对象的属性
  • 3、 globalThis对象

#1、变量声明–let、coust

  • var和let用法类似,let相对于var函数作用域引入块级作用域

    {var a = 10;let b = 20;
    }a // 10
    b // b is not defined.
    
  • 改进var变量提升带来的问题,引入暂时性死区概念,绑定所在区域,不会受外界影响

    // var 
    console.log(foo); // 输出undifined
    var foo = 2;// let 
    console.log(bar); // 报错 ReferenceError
    let bar = 2;
    
    var tmp = 123;
    if(true){console.log(tmp) // ReferenceErrortypeof tmp;      // ReferenceErrortmp = 'abc';     // ReferenceErrorlet tmp;         // 绑定此区域,先于声明之前的使用和赋值会报错
    }
    
  • 不允许重复声明变量,不能在函数内部重新声明参数

    // 报错
    function func(){
    let a = 10;
    var a = 10;
    }// 报错
    function func(arg) {let arg;
    }
    func()// 不报错
    function func(arg) {{let arg;}
    }
    func()
    
  • ES6的块级作用域, 是得变量不存在提升

    ES5 只有全局作用域和函数作用域,没有块级作用域,这带来很多不合理的场景。

    第一种场景,内层变量可能会覆盖外层变量。

    var tmp = new Date();function f() {console.log(tmp);if (false) {var tmp = 'hello world';}
    }f(); // undefined
    

    第二种场景,用来计数的循环变量泄露为全局变量。

    var s = 'hello';for (var i = 0; i < s.length; i++) {console.log(s[i]);
    }console.log(i); // 5
    

    上面代码中,变量i只用来控制循环,但是循环结束后,它并没有消失,泄露成了全局变量。

  • 块级作用域代替了以前常用的匿名立即执行函数表达式(匿名 IIFE )

     // IIFE写法
    (function(){Var tmp = ...;
    })();// 块级作用域写法
    {let tmp = ...;
    }
    
  • const 命令

const声明一个只读的常量。一旦声明,常量的值就不能改变。所以只声明不赋值会报错。

const PI = 3.1415;
PI // 3.1415
PI = 3;
// TypeError: Assignment to constant variable.

const和let一样都不存在变量提升,都不允许重复声明,都不可以在声明前使用。

const 的本质: const 实际上保证的并不是变量的值不得改动,而是变量指向的那个内存地址保存的数据不得改动,因为简单的数据类型,值就保存在指向的那个内存地址,所以相当于常量,但是对于复合类型的数据(对象和数组),变量指向的内存中地址,保存的只是指向实际数据的指针,const只能保证这个指针式固定的,但是它指向的数据结构是不是可变的,就完全不能控制了,因此,将一个对象声明为敞亮必须小心了。

const foo = {};
// foo添加属性
foo.prop = 123;
foo.prop // 123
// 将foo指向另一个对象,就会报错
foo = {}; // TypeError: 'foo' is read-onlyconst arr = [];
arr.push('Hello');
a.length = 0;
a = ['Dave']  // 报错,可以操作不能再赋值

如果想冻结对象本身,需要Object.freeze方法

const foo = Object.freeze({});
// 常规模式下,下面一行代码不起作用,
// 严格模式下,会报错  'use strict'
foo.prop = 123;

对象和对象的属性都冻结的函数,递归

var cosntantize = (obj)=>{Object.freeze(onj);Object.keys(obj).forEach((key,i)=>{if(typeof(obj[key]==='object'){cosntantize(obj[key]);})})
}

#2、顶层对象的属性

浏览器中指window对象,在Node中指global对象,ES5之中,顶层对象的属性与全局变量是等价的。

window.a = 1;
a //1
a = 2
window.a // 2

顶层对象的属性与全局变量挂钩,被认为是JacaScript语言设计的最大败笔,有几大弊端

1、没法在编译时就报出变量未声明的错误,只有在运行时才知道(全局变量可能是又顶层对象的属性创造,而属性创造是动态的)

2、程序会因为手写失误,不自觉创造一个全局变量

3、顶层对象的属性到处可以读写,不利于模块化编程

4、window是一个有实体概念的对象指的就是浏览器窗口对象,但是说顶层对象是有实体的对象是不合适的

ES6为了改变这一点,但是又兼顾兼容性,规定var和function声明的全局变量,依然是顶层对象的属性,另一方面规定let、const 、class命令声明的全局变量,不属于顶层对象的属性,从ES6开始,全局变量将逐渐与顶层对象属性脱钩。

var a = 1;
// 如果Node的REPL环境,可以写成global.a
// 或者this.a
window.a // 1
this.a // 1let b =1;
window.b // undifined
this.b // undifined

#3、globalThis对象

Javascript语言存在一个顶层对象,它提供全局环境(即全局作用域), 所有代码都是在这个谎精中运行,但是顶层对象在各种实现里面是不统一的

比如

  • 浏览器里面,顶层对象是window
  • 浏览器和Web Worker里面,self也指向self
  • Node里面,顶层对象是global,其他环境不支持

为了同样的代码都能取到同样的顶层度喜庆,现在一般用this变量,但是有局限。

  • 全局环境中,this会返回顶层对象,但是Node模块和ES6模块中,this返回的是当前的模块。

  • 函数里面的this,如果函数不是做为对象的方法运行,而是单纯做为函数运行,this会执行顶层对象,但是,严格模式下,会返回undifined。

  • 不管是严格模式,还是普通模式,new Function('return this')(),总是会返回全局对象。但是,如果浏览器用了 CSP(Content Security Policy,内容安全策略),那么evalnew Function这些方法都可能无法使用。

    综上所述,很难找到一种方法,可以在所有情况下,都取到顶层对象。下面是两种勉强可以使用的方法。

    // 方法一
    (typeof window!=='undifined'? 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');
    };
    

ES2020 在语言标准的层面,引入globalThis作为顶层对象。也就是说,任何环境下,globalThis都是存在的,都可以从它拿到顶层对象,指向全局环境下的this

垫片库global-this模拟了这个提案,可以在所有环境拿到globalThis

  • import { connect } from “dva”;

本文发布于:2024-01-30 13:52:48,感谢您对本站的认可!

本文链接:https://www.4u4v.net/it/170659397120458.html

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。

标签:变量   声明
留言与评论(共有 0 条评论)
   
验证码:

Copyright ©2019-2022 Comsenz Inc.Powered by ©

网站地图1 网站地图2 网站地图3 网站地图4 网站地图5 网站地图6 网站地图7 网站地图8 网站地图9 网站地图10 网站地图11 网站地图12 网站地图13 网站地图14 网站地图15 网站地图16 网站地图17 网站地图18 网站地图19 网站地图20 网站地图21 网站地图22/a> 网站地图23