zoukankan      html  css  js  c++  java
  • 你不知道的JavaScript(作用域和闭包)

    作用域和闭包

    ・作用域

      引擎:从头到尾负责整个JavaScript的编译及执行过程。

      编译器:负责语法分析及代码生成等。

      作用域:负责收集并维护由所有声明的标识符(变量)组成的一系列查询,并实施一套非常严格的规则,确定当前执行的代码对这些标识符的访问权限。

      作用域是一套规则,用于确定在何处以及如何查找变量(标识符)。

      如果查找的目的是对变量进行赋值,那么就会使用LHS查询;

      如果目的是获取变量的值,就会使用RHS查询。

    ・词法作用域

      无论函数在哪里被调用,也无论它如何被调用,它的词法作用域都只由函数被声明时所处的位置决定。

      欺骗词法:两种机制。欺骗词法作用域会导致性能下降。

      eval():

      function foo(str, a) {

        eval(str);

        console.log(a, b);

      }

      var b = 2;

      foo(“var b = 3; ”, 1);

      // 1, 3

      with():

      function foo(obj) {

        with(obj) {

      a = 2;

      }

     }

      var o1 = { a: 3};

      var o2 = { b: 3};

      foo(o1);

      console.log(o1.a); // 2

      foo(o2);

      console.log(o2.a); // undefined

      console.log(a); // 2

    ・函数作用域和块作用域

      隐藏内部实现:可以把变量和函数包裹在一个函数的作用域中,然后用这个作用域来隐藏它们。

      最小特权原则(最小授权或最小暴露原则):最小限度地暴露必要内容,而将其他内容都隐藏起来。

      规避冲突:隐藏作用域中的变量和函数,可以避免同名标识符之间的冲突。

      包装函数:

      (function foo() {

        var a = 3;

        console.log(a);

      })();

      匿名函数:

      setTimeout(function() {…}, 1000);

      缺点:

      匿名函数在栈追踪中不会显示出有意义的函数名,使得调试困难;

      如果没有函数名,当需要引用自身时只能使用已过期的arguments.callee引用;

      匿名函数省略了对于代码可读性/可理解性很重要的函数名。

      给函数表达式指定一个函数名可以有效解决以上问题:

      setTimeout(function timeoutHandler() {…}, 1000);

      块作用域:

        let关键字可以将变量绑定到所在的任意作用域中;

        使用let进行的声明不会在块作用域中进行提升;

      提升:

        只有声明本身会被提升,而赋值或其他运行逻辑会留在原地。

        如果提升改变了代码执行的顺序,会造成非常严重的破坏;

      函数声明和变量声明都会被提升,但是函数会首先被提升;

      foo(); // 1

      var foo;

      function foo() {

            console.log(1);

      }

      foo = function() {

            console.log(2);

      }

      ・作用域闭包

        只要使用了回调函数,实际上就是在使用闭包;

      模块模式具备的两个必要条件:

      必须有外部的封闭函数,该函数必须至少被调用一次;

      封闭函数必须返回至少一个内部函数,这样内部函数才能在私有作用域中形成闭包,并且可以访问或者修改私有的状态;

      function CoolModule() {

        var something = “cool”;

          var another = [1, 2, 3];

          function doSomething() {

          console.log(something);

      }

      function doAnother() {

        console.log(another.join(“!”));

      }

      return {

        doSomething: doSomething,

        doAnother: doAnother

      };

     }

      var foo = CoolModule();

      foo.doSomething();

  • 相关阅读:
    支持向量机SVM知识点概括
    决策树知识点概括
    HDU 3081 Marriage Match II
    HDU 3572 Task Schedule
    HDU 4888 Redraw Beautiful Drawings
    Poj 2728 Desert King
    HDU 3926 Hand in Hand
    HDU 1598 find the most comfortable road
    HDU 4393 Throw nails
    POJ 1486 Sorting Slides
  • 原文地址:https://www.cnblogs.com/dreamerjdw/p/6265471.html
Copyright © 2011-2022 走看看