资讯专栏INFORMATION COLUMN

初探ECMAScript 6

xiaotianyi / 1561人阅读

摘要:变量用命令声明,不会发生变量提升。报错不报错块级作用域实际上为新增了块级作用域。这表示外层代码块不受内层代码块的影响。以下两行都会报错声明变量的六种方法只有两种声明变量的方法命令和命令。之中,顶层对象的属性与全局变量是等价的。

let 与 cost

1.使用 let 关键字声明变量,与使用 var 关键字声明变量书写方式一致;
{
  let a = 10;
  var b = 1;
}

a // ReferenceError: a is not defined.
b // 1

上面代码在代码块之中,分别用 let 和 var 声明了两个变量。然后在代码块之外调用这两个变量,结果let声明的变量报错,var声明的变量返回了正确的值。这表明,let声明的变量只在它所在的代码块有效。

通过一个简单的循环来初步了解使用 let 关键字声明变量 与 传统的 var 关键字声明变量的区别
      var a = [];
      for (var i = 0; i < 10; i++) {
        a[i] = function() {
          console.log(i);
        };
      }
      a[6](); // 10
上面代码中,变量i是var命令声明的,在全局范围内都有效,所以全局只有一个变量i。每一次循环,变量i的值都会发生改变,而循环内被赋给数组a的函数内部的console.log(i),里面的i指向的就是全局的i。也就是说,所有数组a的成员里面的i,指向的都是同一个i,导致运行时输出的是最后一轮的i的值,也就是 10。
      var a = [];
      for (let i = 0; i < 10; i++) {
        a[i] = function() {
          console.log(i);
        };
      }
      a[6](); // 6

而这段代码中,变量i是let声明的,当前的i只在本轮循环有效,所以每一次循环的i其实都是一个新的变量,所以最后输出的是6。你可能会问,如果每一轮循环的变量i都是重新声明的,那它怎么知道上一轮循环的值,从而计算出本轮循环的值?这是因为 JavaScript 引擎内部会记住上一轮循环的值,初始化本轮的变量i时,就在上一轮循环的基础上进行计算。

2.不存在变量提升

// var 的情况
console.log(foo); // 输出undefined
var foo = 2;

// let 的情况
console.log(bar); // 报错ReferenceError
let bar = 2;

上面代码中,变量foo用var命令声明,会发生变量提升,即脚本开始运行时,变量foo已经存在了,但是没有值,所以会输出undefined。变量bar用let命令声明,不会发生变量提升。这表示在声明它之前,变量bar是不存在的,这时如果用到它,就会抛出一个错误。

3.暂时性死区

在代码块内,使用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
}

上面代码中,存在全局变量tmp,但是块级作用域内let又声明了一个局部变量tmp,导致后者绑定这个块级作用域,所以在let声明变量前,对tmp赋值会报错

4.不允许重复声明

let不允许在相同作用域内,重复声明同一个变量。
// 报错
function func() {
  let a = 10;
  var a = 1;
}

// 报错
function func() {
  let a = 10;
  let a = 1;
}
因此,不能在函数内部重新声明参数。
function func(arg) {
  let arg;
}
func() // 报错

function func(arg) {
  {
    let arg;
  }
}
func() // 不报错

5.块级作用域

let实际上为 JavaScript 新增了块级作用域。
function f1() {
  let n = 5;
  if (true) {
    let n = 10;
  }
  console.log(n); // 5
}

上面的函数有两个代码块,都声明了变量n,运行后输出 5。这表示外层代码块不受内层代码块的影响。如果两次都使用var定义变量n,最后输出的值才是 10

6.const

const声明一个只读的常量。一旦声明,常量的值就不能改变。
const PI = 3.1415;
PI // 3.1415

PI = 3;
// TypeError: Assignment to constant variable.
const声明的变量不得改变值,这意味着,const一旦声明变量,就必须立即初始化,不能留到以后赋值

const的作用域与let命令相同:只在声明所在的块级作用域内有效
if (true) {
  const MAX = 5;
}

MAX // Uncaught ReferenceError: MAX is not defined
const命令声明的常量也是不提升,同样存在暂时性死区,只能在声明的位置后面使用

const声明的常量,也与let一样不可重复声明。
var message = "Hello!";
let age = 25;

// 以下两行都会报错
const message = "Goodbye!";
const age = 30;
ES6 声明变量的六种方法
ES5 只有两种声明变量的方法:var命令和function命令。ES6 除了添加let和const命令;还有import命令和class命令(这两与本文关系不大,了解即可)

7.顶层对象的属性

顶层对象,在浏览器环境指的是window对象,在 Node 指的是global对象。ES5 之中,顶层对象的属性与全局变量是等价的。
window.a = 1;
a // 1

a = 2;
window.a // 2

上面代码中,顶层对象的属性赋值与全局变量的赋值,是同一件事。
ES6 为了改变这一点,一方面规定,为了保持兼容性,var命令和function命令声明的全局变量,依旧是顶层对象的属性;另一方面规定,let命令、const命令、class命令声明的全局变量,不属于顶层对象的属性
而在ES6(ECMAScript 6 以下简称 ES6)语法中,就会报错

var a = 1;
let b = 1;
window.b // undefined

上面代码中,全局变量a由var命令声明,所以它是顶层对象的属性;全局变量b由let命令声明,所以它不是顶层对象的属性,返回undefined。

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/102300.html

相关文章

  • ES6初探

    摘要:可以直译为古怪到有魅力。里面基本上这些是被弱化了的,或者说是被隐藏起来了。而之前的的语法使得入门的门槛变高了。但是,于此同时,作为语言的独特魅力被削弱了。应该说,理解这些传统的语法对也很有意义。因为毕竟这些只是被隐藏,而不是被剔除。 这两天在看React的一些东西。接触到了ES6。谈谈一些粗浅的看法。 ES6其实是个简称。这东西学名叫做ECMAScript 2015,或者ES 2015...

    tianyu 评论0 收藏0
  • node初探 以及与 浏览器的 差异

    摘要:当发出一个请求的时候,如果这个请求需要等待,那就会被放入队列中,如果有别的请求发出,并且无需等待则立刻做出处理,之后,再调用该请求的回调。差异相对于浏览器而言是没有对象的也没有浏览器安全级别的限制也不具备只能运行 node初体验 1、node环境 node 是一个服务端JavaScript解析器,node中this指向global,而在浏览器中this指向window 所以unde...

    Caicloud 评论0 收藏0
  • this 初探

    摘要:经济基础决定上层建筑。以下暂不考虑严格模式。在全局执行下,无论是否在严格模式下,指向全局对象。在其他函数内部的箭头函数,这些箭头函数的保留。当一个用于在的事件监听中,指向这个元素。 经济基础决定上层建筑。 我来了 学习,记录,备忘。 感谢参考过的所有资料的作者。 嗯,能看源码的就不要看文档,能看英文文档的就不要看中文文档,能自己上手验证的就不要仅仅参考。请保持质疑。深有所感。 t...

    weij 评论0 收藏0
  • React初探

    摘要:绑定事件后的返回值。设置属性,将要设置的新属性,该状态会和当前的合并,可选参数,回调函数。方法与类似,但它会删除原有强制更新参数说明,可选参数,回调函数。判断组件挂载状态返回值或,表示组件是否已挂载到中方法用于判断组件是否已挂载到中。 React 特点 声明式设计 −React采用声明范式,可以轻松描述应用。 高效 −React通过对DOM的模拟,最大限度地减少与DOM的交互。 灵活...

    张金宝 评论0 收藏0
  • Android Flutter实践内存初探

    摘要:摘要实践内存初探闲鱼技术匠修我们想使用来统一移动开发并做了一些实践。将内存管理分为新生代和老年代。在标记阶段,所有线程参与并发的完成对回收对象的标记,降低标记阶段耗时。的首帧渲染耗时较高,在版本有明显感受,大概会黑屏秒,版本会好很多。 摘要: Android Flutter实践内存初探 闲鱼技术-匠修我们想使用Flutter来统一移动App开发并做了一些实践。移动设备上的资源有限,通常...

    dabai 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<