应该说TDZ在JS中是一个比较新的概念,在规范里我也没有搜到对这个概念的具体定义,主要涉及let/const,函数参数默认值,subclass等的使用中。

(一)下面先看let/const中的TDZ问题,规范中这样写到:

13.3 let and const declarations define variables that are scoped to the running execution context’s LexicalEnvironment. The variables are created when their containing Lexical Environment is instantiated but may not be accessed in any way until the variable’s LexicalBinding is evaluated. A variable defined by a LexicalBinding with an Initializer is assigned the value of its Initializer’s AssignmentExpression when the LexicalBinding is evaluated, not when the variable is created. If a LexicalBinding in a let declaration does not have an Initializer the variable is assigned the value undefined when the LexicalBinding is evaluated.

看个通俗的代码示例在解释:

 'use strict';{    // enter new scope, TDZ startstmp = 'abc'; // Uncaught ReferenceError: tmp is not definedconsole.log(tmp); // Uncaught ReferenceError: tmp is not definedlet tmp; // TDZ ends, `tmp` = `undefined`console.log(tmp); // undefinedtmp = 123;console.log(tmp); // 123}

规范中的意思就是,用let/const声明的变量,在声明之前访问时,会抛出ReferenceError。而用var声明的变量,声明之前访问它的时候,值会默认为undefined。

仔细看规范中的描述,在进入一个scope之后,let/const也会有一个hoist,这个过程和var一样,区别是var在hoist之后,被初始化为了undefined,但是let/const没有初始化,直到真正声明它的地方。

在看一个例子:

{ // enter new scope, TDZ startsconst func = function () {console.log(myVar); // OK!};//这之后//访问myVar都会报ReferenceError//这之前let myVar = 3; // TDZ endsfunc();
}

上面这个例子说明了TDZ是一个动态的问题,就是真正访问这个变量时才会进行这种检查。

在看几个代码示例:

1:

let x = x;//Uncaught ReferenceError: x is not defined

2:

let a = f();
const b = 2;
function f() { return b; }//Uncaught ReferenceError: b is not defined

3:

{
console.log(typeof tmp); // Uncaught ReferenceError: tmp is not defined
let tmp;
}

对于第一个,第二个例子,请仔细对照规范去理解。对于第三个例子,想要检查一个let/const变量的类型,可以在非strict mode下用window.tmp去做检查,但并不推荐这样做,因为没有什么好的理由要这样去检查。

*以上全部代码在Chrome 47下通过测试

(二)下面看函数参数默认值中的TDZ问题

*以下全部代码在Kinoma Studio下通过测试,Chrome 47还不支持函数参数默认值

let b = 1;
(function(a = b, b) {//Error: get b: not initialized yet!trace(a + b);
}(undefined, 2));(function(a = a) {}());//Error: get a: not initialized yet!

函数参数列表这里其实形成了一个作用域,这个作用域介于函数外层作用域和函数体作用域之间,我把上面的代码转换一下,就更容易理解了:

let b = 1;
(function({let a = b; let b}) {//把这里当成一个作用域trace(a+b);
}(undefined, 2));

然后在根据规范中对let的描述,就知道为什么a=b这里会报异常了,同样,a=a这里也会报错

对函数参数默认值更深入的理解,后面的章节中会具体讲解


(三)subclass中的TDZ问题

*以下全部代码在Chrome 47下通过测试

 'use strict';class A{}class B extends A{constructor(x){this.x = x;//Uncaught ReferenceError: this is not defined}}var b = new B(0);console.log(b.x);

上面这里的this是在父类里创建出来的,如果在使用this之前,没有调用super(),会认为this没有被定义。具体class的讲解请后面会有,这里就不详细解释了。



*文章参考:http://jsrocks.org/2015/01/temporal-dead-zone-tdz-demystified/


ES6学习——新的语法:Temporal Dead Zone(TDZ)相关推荐

  1. JS基礎:Hoisting 變量提升、TDZ 暫時性死區(Temporal Dead Zone)

    JS 基礎:Hoisting 變量提升.TDZ 暫時性死區(Temporal Dead Zone) 文章目錄 JS 基礎:Hoisting 變量提升.TDZ 暫時性死區(Temporal Dead Z ...

  2. es6学习笔记2-—symbol、变量与作用域

    1.新的字符串特性 标签模板: String.raw(callSite, ...substitutions) : string 用于获取"原始"字符串内容的模板标签(反斜杠不再是转 ...

  3. 【ES6】阮一峰ES6学习(一) let、const、解构赋值

    let 和 const 命令 1. let 概念:块级作用域. 不存在变量提升:在声明变量前使用该变量,会报错. 暂时性死区:形成了封闭作用域,在代码块内,使用let声明变量之前,该变量都是不可用的. ...

  4. ES6学习笔记--let和const

    今天开始读阮一峰的<ECMAScript 6 入门>,在这里记录下阅读过程中的要点,以便随时查阅. let和const 顶层对象的属性与全局变量挂钩,被认为是js最大的败笔之一,ES6开始 ...

  5. 商城项目介绍以及ES6的新语法

    0.学习目标 了解电商行业 了解乐优商城项目结构 能独立搭建项目基本框架 能参考使用ES6的新语法 1.了解电商行业 学习电商项目,自然要先了解这个行业,所以我们首先来聊聊电商行业 1.1.项目分类 ...

  6. ES6学习(十一)—Class 的基本语法和继承

    ES6学习(十一)-Class 的基本语法和继承

  7. ES6学习(九)—Generator 函数的语法

    ES6学习(九)-Generator 函数的语法 Generator 函数是 ES6 提供的一种异步编程解决方案,语法行为与传统函数完全不同. Generator函数是一个状态机,内部封装了不同状态的 ...

  8. ES6学习笔记(四):教你轻松搞懂ES6的新增语法

    文章目录 let const let.const.var的区别 解构赋值 数组解构 对象解构 箭头函数 剩余参数 总结 let ES6新增的用于声明变量的关键字 let声明的变量只在所处于的块级有效 ...

  9. Flutter学习之Dart语法特性

    一.前言 第一天把Flutter环境搭建了,并简单实现第运行第一个Flutter项目,感觉很不错,一些基本操作和原生体验差不多.用Flutter框架写过App项目的开发者都知道,Flutter是一个使 ...

最新文章

  1. 基础 HTML之目录问题(相对路径和绝对路径区别)
  2. 高并发简单解决方案————redis队列缓存+mysql 批量入库(ThinkPhP)
  3. 机器人动力学方程的性质
  4. Crawler之Scrapy:Scrapy简介、安装、使用方法之详细攻略
  5. idea 中javax.servlet.http.HttpServlet包导不进来
  6. 8086汇编贪吃蛇(随机食物+速度递增)
  7. vue中前端处理token过期的方法与axios请求拦截处理
  8. C#检查json格式是否合法
  9. Objective-C语法之字符串NSString去掉前后空格或回车符(可以是NSCharacterSet类型的其它字符)...
  10. 【Java数据库】使用properties资源文件,简化数据库连接
  11. mapreduce分组统计_mongodb中使用mapreduce进行分组统计
  12. 获取Linux命令源代码的方法【ZT】
  13. 2018网易内推 堆棋子 规律题
  14. 人生成功的十大说话技巧
  15. 移动端web轮播图插件swiper,功能很强大
  16. Unity导出转换微信小游戏
  17. Linux系统下安装Adobe Flash Player插件观播放视频
  18. Android 人脸解锁源码剖析
  19. SSIS 学习之旅 SSIS 简介
  20. youtube 可以下载一些英语

热门文章

  1. PHP正则过滤处理微信昵称中emoji字符的方法(导出excel)
  2. 查看java进程占用内存_如何查看java进程大批占用内存
  3. 怎样看计算机显卡等信息,如何看电脑显卡信息 如何判断显卡性能的好坏
  4. OpenWRT-Wifidog之利用Luci认证
  5. python研究背景和意义_课题设计研究的背景和意义
  6. 计算机应用苹果笔记,使用感受 篇一:为什么我不推荐ipad+apple pencil记笔记(一反主流)...
  7. 平果手机桌面计算机,苹果手机怎么做老系统文件夹-苹果手机桌面怎么建文件夹...
  8. Word文件打开的时候需要输入密码?
  9. Handler sync barrier(同步屏障)
  10. 用线程加锁模拟红绿灯