资讯专栏INFORMATION COLUMN

JS学习笔记——闭包

Karuru / 505人阅读

摘要:什么是闭包定义我所理解的闭包就是,即使外部函数已经运行完毕,内部函数仍能访问外部函数的作用域中的变量。闭包的应用场景私有变量模块需求只能通过函数提供的方法访问函数内部的变量隐藏。为什么闭包很重要参考资料征服面试什么是闭包

1. 什么是闭包

MDN定义:Closures are functions that refer to independent (free) variables (variables that are used locally, but defined in an enclosing scope). In other words, these functions "remember" the environment in which they were created.

You Don"t Know JS: Closure is when a function is able to remember and access its lexical scope even when that function is executing outside its lexical scope.

我所理解的闭包就是,即使外部函数已经运行完毕,内部函数仍能访问外部函数的作用域中的变量。

抓重点: 函数, 作用域。
2. 闭包的运行机制 2.1 词法作用域查找规则

在闭包的使用中,为什么我们能够通过闭包访问外部函数的作用域中的变量?其一,词法作用域的查找规则是“冒泡”的,即向外层一层层查找,直到全局作用域,所以能够访问外部函数的作用域。其二,函数的作用域是定义时所在的作用域,而不是运行时的作用域。

function foo() {
  var a = 1;
  
  function bar() {
      console.log(a);
  }
 
 return bar;
}

var a = 2;
var baz = foo();
baz(); //1

在上面的代码中,由于bar定义在foo的内部,因此能够向外“冒泡”访问foo的作用域。当运行baz时,a的值为1而不是2,也说明了函数的作用域是定义时的作用域,是静态的。

2.2 垃圾回收 + 引用

当函数执行完毕后,引擎的垃圾回收机制会释放不再使用的内存空间。因此,当外部函数执行完毕时,外部函数的内部作用域理应是该被销毁的。然而,由于闭包存在对外部函数作用域的引用,因此此作用域仍然存在,所以内部函数仍能在外部函数执行结束之后访问外部函数定义的变量,此之为“记住”

3. 闭包的应用场景 3.1 私有变量 + 模块

需求:只能通过函数提供的方法访问函数内部的变量——隐藏。只能内部访问——私有。

function bookInfo() {
  var book = {
        name: "You Don"t know JS",
      price: 66
    };
        
    function getPrice() {
        console.log(book.price);
    };
    
    function getName() {
        console.log(book.name);
    };
    
    function setPrice(price) {
        book.price = price;
    };
    
    return {
        getPrice,
      getName,
      setPrice
    };
  };

  var book = bookInfo();
  
  book.getPrice(); //66
  book.getName(); //"You Don"t know JS"
  book.setPrice(100);
  book.getPrice(); //100

在以上的代码中,bookInfo通过返回一个对象,该对象的值是对内部函数的引用,而不是对变量的引用。因此,实现了函数内部变量是隐藏的(只能通过返回的对象方法访问)且私有的(只有函数内部才能访问)。

在模块中,返回的变量就被称为模块的公共API,模块内部的变量只能通过这些方法去使用。

3.2 偏函数应用

需求:函数需要先接受一些参数,随后再接受另一些参数的时候。
比如,当我计算商品的总价格时,我想先设定商品的单价,随后根据购买数量算出总的商品价格。

  function partialApply(fn, ...fixedArgs) {
    return function (...remainingArgs) {
        return fn.apply(this, fixedArgs.concat(remainingArgs));
    }
  }
  
  function calTotalPrices(price, count) {
      console.log(price * count);
  }
  
  var pay = partialApply(calPrice, 10);
  
  pay(5);

在上面的代码中,pay就是在partialApply的外部访问了partialApply的内部变量(函数参数)。

4. 为什么闭包很重要? 参考资料

征服 JavaScript 面试:什么是闭包?| Eric Elliott

You Don"t know JavaScript

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/81448.html

相关文章

  • Js学习笔记闭包

    摘要:一前言这个周末,注意力都在学习基础知识上面,刚好看到了闭包这个神圣的东西,所以打算把这两天学到的总结下来,算是巩固自己所学。因此要注意闭包的使用,否则会导致性能问题。五总结闭包的作用能够读取其他函数内部变量。 # 一、前言 这个周末,注意力都在学习基础Js知识上面,刚好看到了闭包这个神圣的东西,所以打算把这两天学到的总结下来,算是巩固自己所学。也可能有些不正确的地方,也请大家看到了,麻...

    Crazy_Coder 评论0 收藏0
  • JS学习笔记(第7章)(函数表达式)

    摘要:递归闭包模仿块级作用域私有变量小结在编程中,使用函数表达式可以无需对函数命名,从而实现动态编程。匿名函数也称为拉姆达函数。函数声明要求有名字,但函数表达式不需要。中的函数表达式和闭包都是极其有用的特性,利用它们可以实现很多功能。 1、递归 2、闭包 3、模仿块级作用域 4、私有变量 5、小结 在JavaScript编程中,使用函数表达式可以无需对函数命名,从而实现动态编程。匿名函数也称...

    xiaokai 评论0 收藏0
  • [学习笔记] JavaScript 闭包

    摘要:但是,必须强调,闭包是一个运行期概念。通过原型链可以实现继承,而与闭包相关的就是作用域链。常理来说,一个函数执行完毕,其执行环境的作用域链会被销毁。所以此时,的作用域链虽然销毁了,但是其活动对象仍在内存中。 学习Javascript闭包(Closure)javascript的闭包JavaScript 闭包深入理解(closure)理解 Javascript 的闭包JavaScript ...

    sunsmell 评论0 收藏0
  • JS笔记

    摘要:从最开始的到封装后的都在试图解决异步编程过程中的问题。为了让编程更美好,我们就需要引入来降低异步编程的复杂性。异步编程入门的全称是前端经典面试题从输入到页面加载发生了什么这是一篇开发的科普类文章,涉及到优化等多个方面。 TypeScript 入门教程 从 JavaScript 程序员的角度总结思考,循序渐进的理解 TypeScript。 网络基础知识之 HTTP 协议 详细介绍 HTT...

    rottengeek 评论0 收藏0
  • js学习笔记闭包

    摘要:本实例来自语言精粹构造器调用模式闭包变成了私有属性当函数返回时,方法依然可以访问,函数可以访问他被创建时所处山下文环境,这就是闭包。 本实例来自《javascript语言精粹》 构造器调用模式: var Quo = function(string){ this.status = string; }; Quo.prototype.get_status=function(){ ...

    Tony_Zby 评论0 收藏0

发表评论

0条评论

Karuru

|高级讲师

TA的文章

阅读更多
最新活动
阅读需要支付1元查看
<