块级作用域绑定

一 var 声明及变量提升(Hoisting)机制

   在函数作用域或全局作用域中通过 var 声明的变量,无论实际上是在哪里声明的,都会被当成在当前作用域顶部声明的变量,这就是我们常说的提升(Hoisting)机制。下面以一个函数为例来说明:

function getValue(condition)
{
if (condition){
var value = "blue";
// 其他代码
return value; }else
{
// 此处可访问变量 value,其值为undefined
return null; }
}

 

  如果你不熟悉 JavaScript,可能会认为只有当 condition 的值为 true 时才会创建变量 value 。事实上,无论如何变量 value 都会被创建。在编译阶段,JavaScript 引擎会将上面的 getValue 函数修改成下面这样:

function getValue (condition){
var value;
if (condition){
value = "blue";
// 其他代码
return value;
}
else{
return null;
}
}

  变量 value 的声明被提升至函数顶部,而初始化操作依旧留在远处执行,这就意味着在 else 子句中也可以访问到该变量,且由于此时变量尚未初始化,所以其值为 undefined。

二 块级声明

  块级声明用于声明在指定块的作用域之外无法访问的变量。块级作用域(亦被称为词法作用域)存在于:

  • 函数内部
  • 块中(字符{和}之间的作用域)

  很多类 C语言都有块级作用域,而 ECMAScript 6 引入块级作用域就是为了让 JavaScript 更灵活更普遍。

let 声明

  let 声明的用法与 var 相同。 用 let 代替 var 来声明变量,就可以把变量的作用域限制在当前代码块中。由于 let 声明不会被提升,因此开发者通常将 let 声明语句放在封闭代码块的顶部,以便整个代码块都可以访问。下面是 let 声明的示例:

function getValue(condition)
{
if (condition){
var value = "blue";
// 其他代码
return value; }else
{
// 变量 value 在此处不存在
return null; }
// 变量 value 在此处不存在
}

禁止重声明

  假设作用域中已经存在某个标识符,此时在用 let 关键字声明它就会抛出错误,举例来说:

var count = 30;

// 抛出错误
let count = 10;

  在这个示例中,变量 count 被声明了两次:一次是用 var 关键字,一次是用 let 关键字。如前所述,同一作用域中不能用 let 重复定义已经存在的标识符,所以此处的 let 声明会抛出错误。但如果当前作用域内嵌另一个作用域,便可在内嵌作用域中用 let 声明同名变量,示例代码如下:

var count = 30;
if (condition){
// 不会抛出错误
let count = 40;
// 更多代码
}

  由于此处的 let 实在 if 块内声明了新变量 count ,因此不会抛出错误,内部块中的 count 会遮蔽全局作用域中的 count,后者只有在 if 块外才能访问到。

const 声明  

  ECMAScript 6 标准还提供了 const 关键字。使用 const 声明的是常量,其值一旦被设定后不可被更改。因此,每个通过 const 声明的常量必须进行初始化,示例如下:

const maxItems = 30;  // 没有问题

const name;// 语法错误,常量未初始化

  在这里声明 maxItems 时进行了初始化操作,而声明 name 时没有进行赋值,因此之行后者时会抛出语法错误。

conse 和 let

  const 与 let 声明都是块级标识符,所以常量也只有在当前代码块内有效,一旦执行到块外会立即被销毁。常量同样也不会被提升至作用域顶部,示例代码如下:

if (condition){
const maxItems = 5;
// 更多代码 } // 此处无法访问 maxItems

  在这段代码中,在 if 语句中声明了常量 maxItems, 语句执行一结束,maxItems 即刻被销毁,在代码块外访问不到这个常量。

  与 let 相似,在同一作用域 中用 const 声明已经存在的标识符也会导致语法错误,无论该标识符使用 var ,还是 let 声明的。举例来说:

var message = "hello!";
let age = 5; // 这两条语句都会抛出错误
const message = "Goodbye!";
const age = 30;

  后两条 const 声明语句本身没问题,但由于前面的 var 和 let 声明了两个同名变量,结果代码就无法执行了。

用 const 声明对象

  记住,const 声明不允许修改绑定,但允许修改值。这就意味着用 const 声明对象后,可以修改该对象的属性值。举个例子:

const max = 5;
// 抛出语法错误
max = 6; const person = {
name = "wz"
};
// 可以修改对象属性的值
person.name = 'mm'; //抛出语法错误 person = {
name = "mm"
}

  这段代码中,绑定 person 的值是一个包含一个属性的对象,改变person.name 的值,不会抛出任何错误,因为修改的是 person 包含的值。如果直接给 person 赋值,即要改变 person 的绑定,就会抛出错误。切记 const 声明不允许修改绑定,但允许修改绑定的值。

es6学习 1的更多相关文章

  1. ES6学习目录

    前面的话 ES6是JavaScript语言的下一代标准,已经在 2015 年 6 月正式发布.它的目标,是使得 JavaScript 语言可以用来编写复杂的大型应用程序,成为企业级开发语言 为什么要学 ...

  2. es6学习笔记-class之继承

    继承 上一篇学习了class的概念,在es5时,对象的继承有好几种,原型链继承,借用构造函数继承,组合继承,原型式继承,寄生式继承以及寄生组合式继承,都是按照函数的形式去集成的,现在class也有它的 ...

  3. es6学习笔记-class之一概念

    前段时间复习了面向对象这一部分,其中提到在es6之前,Javasript是没有类的概念的,只从es6之后出现了类的概念和继承.于是乎,花时间学习一下class. 简介 JavaScript 语言中,生 ...

  4. javascript的ES6学习总结(第二部分)

    1.数组循环 介绍数组循环之前,先回顾一下ES5数组的循环 (1)数组遍历(代替普通的for):arr.forEach(callback(val,index,arr){todo}) //val是数组的 ...

  5. javascript的ES6学习总结(第一部分)

    ES6(ESNext学习总结——第一部分) ES6, 全称 ECMAScript 6.0 ,是 JavaScript 的下一个版本标准,2015.06 发版. ECMA每年6月份,发布一个版本 201 ...

  6. ES6学习笔记<五> Module的操作——import、export、as

    import export 这两个家伙对应的就是es6自己的 module功能. 我们之前写的Javascript一直都没有模块化的体系,无法将一个庞大的js工程拆分成一个个功能相对独立但相互依赖的小 ...

  7. ES6学习笔记<四> default、rest、Multi-line Strings

    default 参数默认值 在实际开发 有时需要给一些参数默认值. 在ES6之前一般都这么处理参数默认值 function add(val_1,val_2){ val_1 = val_1 || 10; ...

  8. ES6学习笔记<三> 生成器函数与yield

    为什么要把这个内容拿出来单独做一篇学习笔记? 生成器函数比较重要,相对不是很容易理解,单独做一篇笔记详细聊一聊生成器函数. 标题为什么是生成器函数与yield? 生成器函数类似其他服务器端语音中的接口 ...

  9. ES6学习笔记<二>arrow functions 箭头函数、template string、destructuring

    接着上一篇的说. arrow functions 箭头函数 => 更便捷的函数声明 document.getElementById("click_1").onclick = ...

  10. ES6学习笔记<一> let const class extends super

    学习参考地址1  学习参考地址2 ECMAScript 6(以下简称ES6)是JavaScript语言的下一代标准.因为当前版本的ES6是在2015年发布的,所以又称ECMAScript 2015:也 ...

随机推荐

  1. Ckeditor 中粘贴图片

    我们在ckeditor 中有上传图片,但是实际使用中这种手动上传图片方式并不是很方便,而是复制或者截图粘贴图片. 这里我们实现主要是获取对应的粘贴事件. CKEDITOR.instances[&quo ...

  2. 最意想不到的5个APP UI 设计范例

    现如今,智能手机已成为人们生活中不可或缺的一个物件,琳琅满目的手机APP充斥着各大应用市场.对于普通人来说,他们的衣食住行因此而变得简单方便:对设计师们来说,他们则面临更多的机遇和挑战.每位设计师都梦 ...

  3. linux 修改oracle字符集

    问题描述:同事在Linux下安装的Oracle,默认的字符集没有修改,使用的是WE8ISO8859P1,不能够支持中文, 问题表现为,客户端录入的中文数据可以显示,提交之后再查询出来后中文会显示为?? ...

  4. Android 上传文件到XP

    Android部分: AsyncHttpClient client = new AsyncHttpClient(); RequestParams requestParams = new Request ...

  5. thinkphp 调用wsdl接口实例化SoapClient抛出异常

    异常:Message:SOAP-ERROR: Parsing WSDL: Couldn't load from 'http://*****?wsdl' : failed to load externa ...

  6. eclipse中maven install提示编码GBK的不可映射字符

    今天在eclipse中使用Maven编译项目源代码时,结果如下了如下的错误 在Java源码中没有提示任何报错,即便是改掉项目编码也是不行,如下图所示:

  7. OpenGL中的需要注意的细节问题

    OpenGL中的需要注意的细节问题 1. 虽然我们使用Windows的BMP文件作为纹理时,一般是蓝色的像素在最前,其真实的格式为GL_BGR而不是GL_RGB,在数据的顺序上有所 不同,但因为同样是 ...

  8. 团队博客第三周(Running Duck队)

    代码链接:Tetris 码云链接 一.需求&原型改进 1.原型改进 汉字方块每次可生成一个并逐渐下落 可通过触摸左右下滑动实现方块的左右移动和快速下滑 左上角按钮可对汉字进行暂时保存和替换 右 ...

  9. DI延伸

    延迟初始化Bean 延迟初始化也叫做惰性初始化,指不提前初始化Bean,而是只有在真正使用时才创建及初始化Bean. 配置方式很简单只需在<bean>标签上指定 “lazy-init” 属 ...

  10. SpringMvc与Struts2的对比

    目前企业中使用SpringMvc的比例已经远远超过Struts2,那么两者到底有什么区别,是很多初学者比较关注的问题,下面我们就来对SpringMvc和Struts2进行各方面的比较: 1.核心控制器 ...