美文网首页我爱编程
上卷 第一部分 第三章 函数作用域和块作用域

上卷 第一部分 第三章 函数作用域和块作用域

作者: nymlc | 来源:发表于2018-04-14 19:02 被阅读0次

前言

实现模块化的先决得理解作用域

函数中的作用域

// b1
var a = function b() {
    b(); // ①
}
// b2
function b() {
    console.log(444);
}
a();
b(); // ②

这里有个很神奇的地方就是①处的b方法调用的是b1,②处调用的b方法是b2,且如果没有b2那么②处将抛异常,查询不到b方法。

这个原因在于该函数声明是作为表达式使得其具名被限定在函数之内,使得在其函数内部仍可引用

隐藏内部实现

最小特权原则:在软件设计中应该最小限度的暴露内容
就是声明一个函数,然后把相应的函数写入其内作为内部函数,达到隐藏目的。

函数作用域

具名函数至少暴露了该函数(容器),而且还得显示调用,显得不够优雅
有俩解决方式:

  1. 使用匿名回调函数(函数声明必须具名,表达式的话就可有可无):setTimeout
  2. 立即执行函数(jQuery就采取这种,然后将接口挂载在window之上)

具名函数好处
栈追踪、事件监听触发之后解绑需要引用自身、函数有意义一目了然
块作用域

块作用域

先考虑以下俩段代码,我们通常习惯于第一种写法,但是其实它和第二种写法无区别(变量提升),也就是在for循环外面i也可以被引用。
但是很多时候它并不被需要在外部,所以我们需要块作用域,让其限定在块内。

for (var i = 0; i < 10; i++) {
    // ......
}
// <===>
var i;
for (i = 0; i < 10; i++) {
    // ......
}

实现的几种方法
1. with
上文说的with就可以
2. try catch
这里说的不是它的{}带有限定作用,而是下面的error只会生效在catch块内,算是一个奇技淫巧。如下a、b都会提升到全局作用域,而error相当于在catch声明了一个error变量,它被限定在catch之内。
不过很尴尬的是它只接受一个参数,所以声明俩个就无能为力了(个人觉得可以把变量变成对象的属性)

try {
    var a = 1;
    throw 3;
} catch (error) {
    var b = 2;
}
console.log(a); // 1
console.log(b); // 2
console.log(error); // Uncaught ReferenceError: error is not defined

3. let
这是ES6提供的。以前只有var声明变量,现在终于不再只有var了。
它可以把变量限定在作用域之内(通常是{ ... }(if、for等等))。顺带提下它不会变量提升

if (true) {
    let a = 1;
}
console.log(a); // ReferenceError
// 不过上面这种写法不好,它是附在已存在的块作用域之上,此为隐式块
// 推荐做法是显示块,如此移动块安全
if (true) {
    {
        let a = 1;
    }
}
console.log(a); // ReferenceError

俩个好处
一则因为闭包导致的一些数据结构会被引擎保存,用块作用域包裹就会让引擎明白无需保存
二则let置于for循环内除了其声明的变量限定在for块作用域之内而且还会重新绑定(就是把上次循环迭代结束的值重新赋给循环的每一次迭代)

for (let i = 0; i < 10; i++) {
    console.log(i);
}
// <====>
{
    let j;
    for (j = 0; j < 10; j++) {
        let i = j;
        console.log(i);
    }
}

4. const
cosnt和let是一样的,区别在于它声明的是常量
转换工具(变通写法)
算是奇技淫巧吧

// babel
"use strict";

{
    var _a = 1;
    console.log(_a);
}
console.log(a);
// traceur
{
  var a$__0 = 1;
  console.log(a$__0);
}
console.log(a);

相关文章

  • JavaScript 作用域和闭包理解

    作用域: 分为函数作用域,和块级作用域; 函数作用域 函数作用域外面的无法访问函数作用域内部的变量和函数,这样就可...

  • 作用域

    标识符的作用域有函数原型作用域、局部作用域(块作用域)、类作用域和 命名空间(namespace) 作用域 函数原...

  • 第七章 块级作用域、私有变量

    模仿块级作用域 私有变量  js没有块级作用域,只有全局作用域和局部作用域(函数作用域),块级作用域是指某一部分代...

  • 一网打尽 JavaScript 的作用域

    JavaScript 的作用域包括:模块作用域,函数作用域,块作用域,词法作用域和全局作用域。 全局作用域 在任何...

  • JavaScript作用域分类

    JavaScript作用域分类全局作用域局部作用域函数作用域块级作用域catchwithlet 和 const 什...

  • JS的作用域

    JS的作用域: 全局作用域、函数作用域、eval 作用域、块级作用域 全局作用域: 函数作用域: 结果截屏: 说...

  • es6基础知识2

    1. 块作用域 作用域指的是变量的作用范围,js本身具有了全局作用域和函数作用域,es6中新增了块作用域。块作用域...

  • 作用域

    词法作用域,动态作用域,全局作用域,局部作用域,函数作用域,块级作用域,有些地方还能看到隐式作用域和显示作用域。 ...

  • ES6学习-块级作用域、let和const

    一、作用域  在以前的ES5中,作用域只有全局作用域和函数作用域,没有块级作用域。 在函数作用域或全局作用域中通过...

  • 第九天,函数作用域和声明提前

    函数作用域和函数声明提前。 函数作用域,分为全局作用域和部分作用域,在系统执行函数时会自动创建一个作用域,在执行完...

网友评论

    本文标题:上卷 第一部分 第三章 函数作用域和块作用域

    本文链接:https://www.haomeiwen.com/subject/ozeqkftx.html