函数表达式读书笔记2

第七章函数表达式- 闭包章节读书笔记记录。(P178开始闭包-- 

 闭包:闭包是指有权访问另一个函数作用域中的变量的函数, 即闭包的本质是函数。

 首先先复习下JavaScript中的作用域相关的知识点。

  JavaScript的作用域分为全局和局部(函数),

  ES6前的JavaScript没有块级作用域,所以会导致理解上的困惑,如:

if (true) {
    var color = 'blue'; 
}
alert(color); // 输出 blue

  如果是C/C++/Java类似的语言中,color会在if执行完毕后被销毁,但在JavaScript中,if语句中的变量声明会将变量添加到当前的执行环境中(当前执行环境级全局环境),所以alert(color)不会报错,输出blue值。

在使用for语句的时候尤其要牢记改点差异,如:

for(var i =0; i< 10; i++) {
    doSomething(i);
}
alert(i); // 输出10;

  在有块级作用域的语言中,for语句初始化变量的表达式所定义的变量,只会存在于循环的环境中。而对于JavaScript来说,不存在块级作用域,变量i由于变量声明会将变量添加到当前的执行环境中(当前为全局),所以在for循环结束后,变量i未被销毁,一直存在外部的执行环境中,所以会输出10.

  声明变量;

  使用var声明的变量会自动添加到最近的执行环境中,在函数内部,最近的环境就是函数的局部环境中,如果变量没有被var声明,该变量会自动添加到全局环境中,如:

function add(num1, num2) {
    var sum = num1 + num2;
    return sum;
}
var result =add(1, 2);
console.log(sum); // 提示报错

  由于sum通过var 进行声明,所以sum存在的作用域为局部作用域,仅在函数内部使用,所以在函数外部调用变量sum,由于外部中不存在sum变量,所以会报错。如果sum未通过var进行声明,则在外部访问该变量不会报错,如:

function add(num1, num2) {
    sum = num1 + num2;
    return sum;
}
var result = add(1, 2);
console.log(sum); // 输出3

  由于sum未通过var进行声明,所以被添加到全局环境中,所以在add()执行完,sum变量仍存在,所以访问该变量不会报错。

 当某个函数在调用的时候,会创建一个执行环境以及相应的作用域链。然后使用arguments和其他命名参数的值来初始化函数的活动对象,但在作用域链中,外部函数的活动对象始终处在第二位,外部行数的外部函数的活动对象处于第三位,...直至作为作用域链终点的全局执行环境。在函数执行过程中,为读取和写入变量的值,就需要在作用域链中查找变量。如:

function compare(value1, value2) {
    if (value1 < value2)  {    
        return -1;
    } else if (value1 > value2) {
        return 1;
    } else {
        return 0;
    }
}
var result = compare(5, 10);

  

注: 由于闭包会携带包含它的函数作用域,因此会比其他函数占用更多的内存,过度使用闭包,可能会导致内存占用过多。

匿名函数的执行环境具有全局性,所以其this对象通常执行window,当然通过call()或apply()改变函数执行环境的情况下,this就会指向其他对象。

原文地址:https://www.cnblogs.com/lzj0824/p/7019760.html