函数作用域

  Javascript具有基于函数的作用域,每声明一个函数,都会产生一个对应的作用域。

    //全局作用域包含f1
function f1(a) {
var b = 1;
//f1作用域包含a,b,f2
function f2() {
//f2有自己的
//...代码
}
return a + b;
}
//无法从外部访问内部作用域
console.log(b); //error

  

IIFE

   如果需要封装某些变量,但同时不想多出一个函数名与调用函数,可以使用IIFE,立即执行函数。

    var a = 1;
//为了封装a变量需要声明一个函数并同时调用
function fn() {
var a = 2;
console.log(a); //
}
fn();
console.log(a); //
//可以使用IIFE
(function() {
var a = 2;
console.log(a); //
})();

  当函数被括号包起来时,被当成一个函数表达式了,所以可以立即执行,区分函数声明和函数表达式最简单的方法就是看function关键字是否是第一个词。

    console.log(fn()); //
function fn() {
return 1;
}
console.log(fn2()); //error
//匿名函数表达式 不会提升声明
(function fn2() {
return 1;
})

  匿名函数表达式使用很方便,但是也有几个缺点。

  1、调试时无法根据函数名进行追踪。

  2、没有函数名,调用自身只能使用被废弃的arguments.callee。

  3、缺失可读性。

  所以说,作者建议给匿名函数加个函数名就可以了。

  

  IIFE还有另外一种改进形式。

    (function() {
var a = 1;
console.log(a); //
}());

  这两种功能上是一致的。

  IIFE的一个非常普遍的进阶用法是把它们当做函数调用并传递参数进去。

    var a = 2;
(function(global) {
var a = 1;
console.log(a); //
//将传进去的window更名为global
//使得语义更明确 并且解析全局变量时不会一层层作用域查找
console.log(global.a); //
}(window));

  另外一个应用场景是解决undefined标识符的默认值被错误覆盖。(测试不出undefined可以被改变值,暂不贴代码)

  IIFE还有一种变化的用途是倒置代码的运行顺序。将需要运行的函数放后面,IIFE执行之后当参数传进去。

    var a = 2;
(function IIFE(def) {
def(window);
})(function(global) {
var a = 3;
console.log(a); //
console.log(global.a); //
});
//相当于
(function(global) {
var a = 3;
console.log(a); //
console.log(global.a); //
})(window);

  jQuery源码就是用这种形式,当初一脸懵逼,根本看不懂。。。

块作用域

  除Javascript外很多编程语言都支持块作用域。

    //块状作用域
for (var i = 0; i < 10; i++) {
console.loe(i);
}

  然而,JS并没有,表面上没有。

  1、with语句会创建出块级作用域。

  2、try/catch的catch分句会创建一个块级作用域。

let

  ES6引入了let关键字,提供了另外一种变量声明方式。

  let关键字可以将变量绑定到所在的任意作用域中,简单来说,就是提供了块级作用域。

    {
var a = 1;
}
console.log(a); //
{
let b = 1;
}
console.log(b); //error

  let还有两个特性,首先,不会有变量提升。

    {
console.log(a); //error
let a = 1;
}

  第二个就是暂时性死区。

  简单来说,就是在有let的块级作用域中,变量在声明前被暂时锁住,不允许在声明前进行使用。

    var a = 2; //声明全局变量
{
console.log(a); //还是报错了!
let a = 1;
}

  ES6还提供了const关键字,也可以提供块级作用域,意义参照C++。

读书笔记-你不知道的JS上-函数作用域与块作用域的更多相关文章

  1. 读书笔记-你不知道的JS上-词法作用域

    JS引擎 编译与执行 Javascript引擎会在词法分析和代码生成阶段对运行性能进行优化,包含对冗余元素进行优化(例如对语句在不影响结果的情况下进行重新组合). 对于Javascript来说,大部分 ...

  2. 读书笔记-你不知道的JS上-闭包与模块

    闭包定义 当函数可以记住并访问所在的词法作用域时,就产生了闭包,即使函数是在当前词法作用域之外执行. 看一段最简单的闭包代码: function foo() { var a = 2; //闭包 fun ...

  3. 读书笔记-你不知道的JS上-this

    关于this 与静态词法作用域不用,this的指向动态绑定,在函数执行期间才能确定.感觉有点像C++的多态? var a = 1; var obj = { a: 2, fn: function() { ...

  4. 读书笔记-你不知道的JS上-对象

    好想要对象··· 函数的调用位置不同会造成this绑定对象不同.但是对象到底是什么,为什么要绑定他们呢?(可以可以,我也不太懂) 语法 对象声明有两个形式: 1.字面量 => var obj = ...

  5. 读书笔记-你不知道的JS上-声明提升

    变量声明提升 Javascript代码一般情况下是由上往下执行的,但是有些情况下不成立. a = 2; //变量声明被提升在当前作用域顶部 var a; console.log(a); console ...

  6. 读书笔记-你不知道的JS中-函数生成器

    这个坑比较深 可能写完我也看不懂(逃 ES6提供了一个新的函数特性,名字叫Generator,一开始看到,第一反应是函数指针?然而并不是,只是一个新的语法. 入门 简单来说,用法如下: functio ...

  7. 读书笔记-你不知道的JS上-混入与原型

    继承 mixin混合继承 function mixin(obj1, obj2) { for (var key in obj2) { //重复不复制 if (!(key in obj1)) { obj1 ...

  8. 读书笔记-你不知道的JavaScript(上)

    本文首发在我的个人博客:http://muyunyun.cn/ <你不知道的JavaScript>系列丛书给出了很多颠覆以往对JavaScript认知的点, 读完上卷,受益匪浅,于是对其精 ...

  9. 读书笔记-你不知道的JS中-promise

    之前的笔记没保存没掉了,好气,重新写! 填坑-- 现在与将来 在单个JS文件中,程序由许多块组成,这些块有的现在执行,有的将来执行,最常见的块单位是函数. 程序中'将来'执行的部分并不一定在'现在'运 ...

随机推荐

  1. 只用一招让你Maven依赖下载速度快如闪电

    一.背景 众所周知,Maven对于依赖的管理让我们程序员感觉爽的不要不要的,但是由于这货是国外出的,所以在我们从中央仓库下载依赖的时候,速度如蜗牛一般,让人不能忍,并且这也是大多数程序员都会遇到的问题 ...

  2. FoxOne---一个快速高效的BS框架--生成增删改查

    FoxOne---一个快速高效的BS框架--(1) FoxOne---一个快速高效的BS框架--(2) FoxOne---一个快速高效的BS框架--(3) FoxOne---一个快速高效的BS框架-- ...

  3. 巧用Mono.Cecil反射加载类型和方法信息

    最近在做服务的细粒度治理,统一管理所有服务的方法.参数.返回值信息.方便后续的各个模块之间的对接和协作. 目前系统中所有的服务,管理到接口契约粒度,即服务接口声明和服务接口实现.要做服务的细粒度治理: ...

  4. GCD XOR uvalive6657

    GCD XORGiven an integer N, nd how many pairs (A; B) are there such that: gcd(A; B) = A xor B where1 ...

  5. 搭建LAMP环境示例

    html { font-family: sans-serif } body { margin: 0 } article,aside,details,figcaption,figure,footer,h ...

  6. day01:study HTTP协议

    总结: 1.对web客户端和web服务器之间的通讯有了基本原理有了简单理解. 2.对http协议有了相关概念的建立 3.B/S C/S 两种形式 4.搭建tomcat服务器的环境,相关配置(虚拟目录 ...

  7. LCT学习笔记

    最近自学了一下LCT(Link-Cut-Tree),参考了Saramanda及Yang_Zhe等众多大神的论文博客,对LCT有了一个初步的认识,LCT是一种动态树,可以处理动态问题的算法.对于树分治中 ...

  8. Entity Framework Code First实现乐观并发

    Entity Framework Code First实现乐观并发 不定时更新翻译系列,此系列更新毫无时间规律,文笔菜翻译菜求各位看官老爷们轻喷,如觉得我翻译有问题请挪步原博客地址 本博文翻译自: h ...

  9. FPGA在其他领域的应用(四)

    工业领域: 从工厂和过程自动化到能源基础设施和机器视觉系统,工业产品有助于改善我们的世界.产品必须安全.可靠.适应性强,而且耐用.同时,商业成功要求你在激烈竞争的市场中行动迅速,同时降低总成本. 英特 ...

  10. ConvertUtils.register注册转换器

    当用到BeanUtils的populate.copyProperties方法或者getProperty,setProperty方法其实都会调用convert进行转换 但Converter只支持一些基本 ...