Giter Club home page Giter Club logo

Comments (4)

mamba-1024 avatar mamba-1024 commented on August 21, 2024

词法化 (也叫单词化)

大部分标准语言编译器的第一个工作阶段叫做 词法化
词法化的过程会对源代码中的字符进行检查,如果是有状态的解析过程,还会赋予单词语义。

了解了词法化后,下面我们就该说说正题了

词法作用域

词法作用域就是定义在词法阶段的作用域。词法作用域是由你在写代码时将变量和块作用域写在哪里来决定的。
词法作用域意味着作用域是由书写代码时函数声明的位置来决定的。
所以词法作用域又叫静态作用域
因为 JavaScript 采用的是词法作用域,函数的作用域在函数定义的时候就决定了。

var value = 1;
function foo() {
    console.log(value);
}
function bar() {
    var value = 2;
    foo();
}
bar(); // 1

from myblog.

mamba-1024 avatar mamba-1024 commented on August 21, 2024

JavaScript闭包

当函数可以记住并访问所在的词法作用域时,就产生了闭包,即使函数是在当前词法作用 域之外执行。
直接上一个示例代码:

function foo() { 
  var a = 2;
  function bar() {
    console.log( a );
  }
  return bar; 
}
var baz = foo();  // 拿到该函数所在词法作用域中的嵌套函数(可以访问外层函数中的变量)
baz(); // 2 —— 这就是闭包的效果

我们将 bar 所引用的函数对象本身当作返回值,然后赋值给变量 baz 并调用 baz(),实际上只是通过不同的标识符引用调用了内部的函数 bar()。
通常foo() 执行后, foo() 的整个内部作用域都被销毁,引擎的垃圾回收机制会回收不再使用的内存空间。
而闭包的神奇之处就在于阻止这个事情的发生。实际上内部作用域依然存在,没有被回收,因为bar()函数还在使用。
拜 bar() 所声明的位置所赐,它拥有涵盖 foo() 内部作用域的闭包,使得该作用域能够一 直存活,以供 bar() 在之后任何时间进行引用。
bar() 依然持有对该作用域的引用,而这个引用就叫作闭包。

function foo() { 
  var a = 2;
  function baz() {
    console.log( a ); // 2
  }
  bar( baz );  // 1.把内部函数baz传递给bar
}
function bar(fn) {
  fn(); //  2.当调用的时候还可以访问a,这就是闭包!
}
var fn;
function foo() {
  var a = 2;
  function baz() {
    console.log( a );
  }
  fn = baz; // 将 baz 分配给全局变量
}
function bar() {
  fn(); //  这就是闭包!
}
foo();
bar(); // 2

无论通过何种手段将内部函数传递到所在的词法作用域以外,它都会持有对原始定义作用域的引用,无论在何处执行这个函数都会使用闭包。

from myblog.

mamba-1024 avatar mamba-1024 commented on August 21, 2024

常见的闭包

  • 定时器函数setTimeout
function wait(message) {
    setTimeout( function timer() {
         console.log( message );
    }, 1000 ); 
}
wait( "Hello, closure!" );
  • 循环与闭包
for (var i=1; i<=5; i++) { 
  setTimeout( function timer() {
      console.log( i );
   }, i*1000 );
}
console.log => 5次6

在上面代码中,i是定义在全局作用域中的一个变量,定时器的回调函数会在所有的循环执行完毕后才执行的,此时内存中的变量 i 的值等于6,
稍加改进,我们让定时器函数立即执行

for (var i=1; i<=5; i++) { 
  (function(j) {
    setTimeout( function timer() { 
      console.log( j );
      }, j*1000 );
   })( i );
}

from myblog.

mamba-1024 avatar mamba-1024 commented on August 21, 2024

利用闭包实现的模块化

function foo() {
  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 coolModule = foo(); 
coolModule.doSomething(); // cool
coolModule.doAnother(); // 1 ! 2 ! 3

利用闭包,我们可以把函数内部的方法暴露出来,可以在其他地方引用。

from myblog.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.