博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
ECMAScript6(1):块级作用域
阅读量:5974 次
发布时间:2019-06-19

本文共 2356 字,大约阅读时间需要 7 分钟。

let、const和块级作用域

块级作用于对于强类型语言经验的人应该非常好理解, 一言以蔽之:ES5对变量作用于分隔使用了函数(词法作用域), 而ES6使用花括号(块作用域)。

对于词法作用域在 中有详细的解释。对于let 和 const声明的变量在花括号的分割下同样会形成作用于链(内部访问外部的, 但外部不能访问内部)。但是花括号对于没有声明直接定义以及用 var 声明的变量没有影响, 这些变量依然遵守词法作用域规则。

对于let 和 const 最大的好处就是避免了可能的运行时错误, 不过也有直观的好处:

  • 用块(Blocks)替换立即执行函数(IIFEs)
  • 定义循环变量不会外泄
  • 循环定义函数可以不用闭包了
  • 可以放心的在 if 等条件中定义函数
//用块(Blocks)替换立即执行函数(IIFEs)//ES5(function () {  var food = 'Meow Mix';}());console.log(food); // Reference Error//ES6{  let food = 'Meow Mix';}console.log(food); // Reference Error
var a = [];for(let i = 0; i < 10; i++){  a[i] = function(){    console.log(i);  }}a[6]();       //这里输出6, 在var定义i的for循环中输出 10console.log(i);    //ReferenceError
function b(){console.log("outside");}function f(){  if(false){    function b(){console.log("inside");}  }  b();}f();   // ES5 中报错:"TypeError:b is not a function" 而 ES6 中输出"outside"

由此例可以看出 function 定义函数不具有块级作用域。

但我们需要注意的一下几点:

  • let 和 const 声明的变量不在 window 的属性中
var a = 10;let b = 20;const c = 30;console.log(window.a);    //10console.log(window.b);    //undedinedconsole.log(window.c);    //undedined
  • let 和 const 声明的变量没有声明提前, 所以在作用域内存在暂时性死区
var temp = 20;(function area(){  console.log(temp);  //undefined  var temp = 30;      //声明提前}());if(true){  console.log(temp);  //ReferenceError   但是 babel 会得到 undefined  let temp = 20;}
//一个隐蔽的死区function bar(x = y, y = 2){  console.log(x, y);}bar();    //报错, 因为定义 x 的时候, y 还没有定义 (babel 中不报错,得到 undefined 2)function par(x = 2, y = x){  console.log(x, y);}par();    //22
  • let 和 const 声明变量在当前作用域(不包括作用域链)上不能重复。const声明的变量必须初始化, 且不能修改:
let a = 10;var b = 20;const c = 30;let a = 4;    //报错const b = 3;  //报错c = 20;   //报错, c是只读的
  • 不可以连续定义变量
let a=b=3;     //报错 b 未定义const c=d=2;   //报错 d 未定义
  • 技巧:ES6 中, 在块作用于外调用内部函数
var f;{  f = function(){    console.log("inside");  }}f();
  • const 声明的基本变量不可改变, 但复杂变量可以改变其内容

const 这个特性和底层的 c++ 一致, 在 c++ 中 const 相当于常指针 int * const p, 也就是其指向的数据所在内存区域可读可写, 但是指针的值初始后就不能改。

const a = 10;const b = {  num: 20};b.num = 30;console.log(b.num);   //30a = 20;         //TypeErrorb = {  num: 90};              //TypeError

如果想让非基本变量内部也不可改变, 需要使用 Object.freeze() 方法。可以参考:

  • 跨模块常量

对于跨模块的常量, 可以这样写:

// const.js moduleexport const A = 1;export const B = 2;// test.js 文件import * as constants from './const';console.log(constants.A);   //1console.log(constants.B);   //2//orimport {A, B} from './const';console.log(A);   //1console.log(B);   //2

转载地址:http://tudox.baihongyu.com/

你可能感兴趣的文章
L-1-19 Linux之RAID&分区&文件系统命令
查看>>
stat查找权限以数字形式显示
查看>>
Java面向对象学习笔记(二)
查看>>
源码编译安装httpd2.4.9
查看>>
linux系统优化
查看>>
在使用 Windows Update 检查更新时,系统没有提供下载 Windows 7 SP1 的选项
查看>>
CSS控制XML与通过js解析xml然后通过html显示xml中的数据
查看>>
在Struts + Spring + Hibernate的组合框架模式中,三者各自的特点都是什么
查看>>
Windows 2012 R2 DataCenter服务器DNS无法打开AD, DNS错误代码4000 4007 4013
查看>>
网络学习(二十一)创建用户及文件夹共享设置的简单应用
查看>>
java基础数据类型char
查看>>
打印 PE导入导出表
查看>>
miniWindbg 功能
查看>>
五、判断银行卡号的正则
查看>>
mysql基于mysqlslap的压力测试
查看>>
zencart中query_factory.php中连接mysql次数
查看>>
fail2ban 保护linux安全(转载)已用于生产环境
查看>>
if,for,while,case,break,continue,exit
查看>>
表格元素的添加和删除,计算器,全选全不反选
查看>>
数据约束
查看>>