es6暂时性死区是什么意思

在es6中,暂时性死区是一个语法错误,是指let和const命令使区块形成封闭的作用域。在代码块内,使用let/const命令声明变量之前,该变量都是不可用的,在变量声明之前属于该变量的“死区”;这在语法上,称为“暂时性死区”。ES6规定暂时性死区和let、const语句不出现变量提升,主要是为了减少运行时错误,防止在变量声明前就使用这个变量,从而导致意料之外的行为。

es6暂时性死区是什么意思

本教程操作环境:windows7系统、ECMAScript 6版、Dell G3电脑。

什么是暂时性死区 

ES6中,在代码块内,使用let/const命令声明变量之前,该变量都是不可用的,在变量声明之前属于该变量的“死区”。这在语法上,称为“暂时性死区”(temporal dead zone,简称 TDZ)。ES标准并没有明确提出TDZ,但我们常用其描述let、const的不提升效果。

let/const和var的区别

在ES6之前,JS的scope只有两种,全局作用域和函数作用域,但是在ES6种出现了块级作用域,即使用let/const可以定义块级作用域。那么在ES6的新特性中,最容易看到TDZ作用的就是使用let/const的使用上面。let/const与var的主要不同有两个地方:

let/const是使用区块作用域;var是使用函数作用域在let/const声明之前就访问对应的变量与常量,会抛出ReferenceError错误;但在var声明之前就访问对应的变量,则会得到undefined

console.log(Vname); // undefined;console.log(Lname); // ReferenceErrorvar Vname = 'xiaoxiao';let Lname = 'xiaoxiao';

登录后复制

实践证明当我们在未声明之前使用var定义的变量时会得到undefined,但是在使用let未定义的变量时会抛出错误。因为ES6中的let声明的变量是不存在变量提升的作用。

var x = 10;if (true) {    x = 20; // ReferenceError    let x; }

登录后复制

ES6 明确规定,如果区块中存在let和const命令,这个区块对这些命令声明的变量,从一开始就形成了封闭作用域。凡是在声明之前就使用这些变量,就会报错。总之,在代码块内,使用let命令声明变量之前,该变量都是不可用的。这在语法上,称为“暂时性死区”(temporal dead zone,简称 TDZ)。

if (true) {  // TDZ开始  tmp = 'abc'; // ReferenceError  console.log(tmp); // ReferenceError  let tmp; // TDZ结束  console.log(tmp); // undefined  tmp = 123;  console.log(tmp); // 123}

登录后复制

上面代码中,在let命令声明变量tmp之前,都属于变量tmp的“死区”。

typeof的“死区”陷阱

我们都知道使用typeof 可以用来检测给定变量的数据类型,也可以使用它来判断值是否被定义。当返回undefined时表示值未定义;但是在const/let定义的变量在变量声明之前如果使用了typeof就会报错

typeof x; // ReferenceErrorlet x;

登录后复制

因为x是使用let声明的,那么在x未声明之前都属于暂时性死区,在使用typeof时就会报错。所以在使用let/const进行声明的变量在使用typeof时不一定安全喔。

typeof y; // 'undefined'

登录后复制

但是可以看出,如果我们只是用了typeof而没有去定义,也是不会报错的,从这粒可以看出只要没有明确规定使用const/let定义之前就是不会出错。

传参的“死区”陷阱

例如下面一段代码,我们在使用

function bar(x = y, y = 2) {  return [x, y];}bar(); // 报错

登录后复制

上面代码中,调用bar函数之所以报错(某些实现可能不报错),是因为参数x默认值等于另一个参数y,而此时y还没有声明,属于”死区“。如果y的默认值是x,就不会报错,因为此时x已经声明了。

function bar(x = 2, y = x) {  return [x, y];}bar(); // [2, 2]

登录后复制

使用var和let声明的另外一种区别。

// 不报错var x = x;// 报错let x = x;// ReferenceError: x is not defined

登录后复制

受“死区”的影响,使用let声明变量时,只要变量在还没有声明完成前使用,就会报错。上面这行就属于这个情况,在变量x的声明语句还没有执行完成前,就去取x的值,导致报错”x 未定义“。

总结

ES6 规定暂时性死区和let、const语句不出现变量提升,主要是为了减少运行时错误,防止在变量声明前就使用这个变量,从而导致意料之外的行为。这样的错误在 ES5 是很常见的,现在有了这种规定,避免此类错误就很容易了。

总之,暂时性死区的本质就是,只要一进入当前作用域,所要使用的变量就已经存在了,但是不可获取,只有等到声明变量的那一行代码出现,才可以获取和使用该变量。

注: TDZ最一开始是为了const所设计的,但后来的对let的设计也是一致的。

注: 在ES6标准中,对于const所声明的识别子仍然也经常为variable(变量),称为constant variable(固定的变量)。以const声明所创建出来的常量,在JS中只是不能再被赋(can’t re-assignment),并不是不可被改变(immutable)的,这两种概念仍然有很大的差异。

【相关推荐:javascript视频教程、web前端】

以上就是es6暂时性死区是什么意思的详细内容,更多请关注【创想鸟】其它相关文章!

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至253000106@qq.com举报,一经查实,本站将立刻删除。

发布者:PHP中文网,转转请注明出处:https://www.chuangxiangniao.com/p/2922525.html

(0)
上一篇 2025年3月11日 18:39:32
下一篇 2025年3月8日 13:02:27

AD推荐 黄金广告位招租... 更多推荐

相关推荐

  • es6 装饰器怎么理解

    在es6中,装饰者模式是一种在不改变原类和使用继承的情况下,动态地扩展对象功能的设计理论;装饰者其本质就是一个普通的函数,用于扩展类属性和类方法。使用装饰器的优点:1、代码可读性变强了,装饰器命名相当于一个注释;2、在不改变原有代码情况下,…

    2025年3月11日
    200
  • es6新特性都有哪些

    es6新特性有:1、let和const;2、symbol;3、模板字符串;4、解构表达式;5、对象方面,如Map和Set;6、函数方面,如参数默认值和箭头函数;7、class关键字;8、promise和proxy;9、模块化;10、运算符。…

    2025年3月11日
    200
  • es6中includes返回的是什么

    es6中includes()返回的是布尔值。includes()方法用于判断字符串/数组是否包含指定的值,语法“ojb.includes(searchvalue, start)”;如果找到匹配的值则返回true,否则返回false。 本教程…

    2025年3月11日
    200
  • es6 map是引用类型吗

    map是引用类型;map(集合)是es6新增的一种引用数据类型,表示数据的映射关系。map集合数据类型中数据是以“键/值”的方式存储的,可以使用对象的属性作为键,使用属性来引用值;map可以使用new来创建,例“const myMap = …

    2025年3月11日
    200
  • es6箭头函数是函数式编程吗

    是。箭头函数是函数式编程的一种体现,函数式编程将更多的关注点放在输入和输出的关系,省去了过程的一些因素,因此箭头函数中没有自己的this、arguments、new target(ES6)和 super(ES6);箭头函数相当于匿名函数,因…

    2025年3月11日
    200
  • es6的set集合怎么增加元素

    es6的set集合可以使用add()方法来增加元素。Set集合是一种数据结构,结构类似于数组,且没有重复的值;其内置的add()方法可以为集合添加元素,语法“set.add(值);”,添加完成后会返回Set结构本身。 本教程操作环境:win…

    2025年3月11日 编程技术
    200
  • es6怎么声明只读常量

    在es6中,可以使用const关键字来声明只读常量,语法“const 常量名 = 常量值;”;一旦声明,常量必须进行初始化且初始化的值就不能改变。const声明的常量属于块作用域,受到“暂存死区”的约束,不会在window上创建任何全局属性…

    2025年3月11日
    200
  • es6中let怎么用

    在es6中,let关键字用于声明变量;但是所声明的变量,只在let命令所在的代码块内有效。let不会发生“变量提升”现象,所以变量一定要在声明后使用,否则报错。只要块级作用域内存在let命令,它所声明的变量就“绑定”(binding)这个区…

    2025年3月11日
    200
  • es6怎么删除数组中的某一项

    删除方法:1、用splice()根据下标删除任意一个元素,语法“arr.splice(index,1)”;2、用delete关键字根据下标删除任意一个元素,语法“delete arr[index];”;3、用shift()删除第一个元素,语…

    2025年3月11日 编程技术
    200
  • es5和es6怎么实现数组去重

    es5中可以利用for语句和indexOf()函数来实现数组去重,语法“for(i=0;i 本教程操作环境:windows7系统、ECMAScript 6版、Dell G3电脑。 es5 数组去重 indexOf 方法 使用indexOf(…

    2025年3月11日 编程技术
    200

发表回复

登录后才能评论