美文网首页
浅析JS闭包(Closure)与函数的柯里化(Currying)

浅析JS闭包(Closure)与函数的柯里化(Currying)

作者: 野兽仙贝 | 来源:发表于2017-02-26 14:54 被阅读0次

先上版图


塞尔达 荒野之息
//3月3号老任就要发售Switch了,还有塞尔达护航新作好激动呀,然而我并没有钱买...

1、JS闭包

闭包在程序界是一个很抽象的概念,以至于被人称为编程界的哈姆雷特,我们先来看看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.

  • 闭包是一个函数,特指那些可以访问独立变量的函数(这种独立变量在本地使用,但是却定义在一个封闭的作用域),换句话说这类函数能够记忆创建它们时的环境

其实我个人理解更倾向于:

当嵌套函数的引用传递给了嵌套函数作用域之外的变量,或者对象的属性,此时就会形成一个闭包

嗯,解释的很好,但我还是不知道这是个啥
那还是少废话上代码吧。。

function person() {
  var name = 'ergouzi';
  console.log(name);
}
person();
console.log(name);
输出:
//ergouzi
//undefined

很普通的一个函数,正常理解函数与变量的思维就是:函数执行,定义变量,函数执行完毕,变量销毁。再来看看另一种写法

function person() {
  var name = 'ergouzi';
  var nameFunc = function() {
    console.log(name);
  }
  return nameFunc;
}
var personFunc = person();
personFunc();
输出:
//ergouzi

可以看到,这里即使person函数执行完毕了,但是里面的name变量却没有被销毁,这里再套用开头解释的概念,应该能理解部分了吧。咱们再来验证一下这种“被记忆的独立变量”的特性

function person() {
  var name = 'ergouzi';
  var funcObj = {
    'nameFunc': function () {
      console.log(name);
    },
    'changeFunc': function () {
      name = 'goudanzi';
    }
  }
  return funcObj;
}
var funcObj = person();
funcObj.changeFunc();
funcObj.nameFunc();
输出:
//goudanzi

可以看到,我们在该独立变量的作用域外部改变了它的值,所以说明相同环境里创建的闭包函数,引用的独立变量为同一份拷贝,即同一个对象。其实用chrome调试一下就能很清楚的看到闭包函数长啥样,比如我这里的闭包函数它长这样(还长得挺漂亮的)


我们可以看到两个函数“changeFunc”,“nameFunc”,从他们的Scopes里面都能找到Closure并且创建环境都为person,记忆的独立变量都为“name”,

再来看点哦莫西罗伊的

for (var i = 0; i < 10; i++) {
  setTimeout(function(){
    console.log(i)
  }, 0);
}
输出:
//10
//10
//10
//10
//10
//10
//10
//10
//10
//10
//简要解释一下输出值,因为setTimeout是异步函数,在i=0第一次循环时只是定义了第一个定时函数而并没有执行它,待到执行第一个定时函数,但此时i的值已经变了

一个普通的for循环,每次循环定义了一个定时器函数,因为没有给定时器函数的句柄传参,它只能拿到i最后的值。我们换一种“闭包”一点的写法

for (var i = 0; i < 10; i++) {
  setTimeout(((j) => console.log(j))(i), 0);
}
//或者这样写
for (var i = 0; i < 10; i++) {
  (j => setTimeout((j) => console.log(j), 0))(i);
}

这里用到了es6的箭头函数,想详细了解箭头函数请移步箭头函数
这里的代码将每次循环的i值传给了一个闭包函数,此时这个闭包函数记忆了这个i的值,等到执行定时函数时,就可以正常打印出i值。

参考文档https://developer.mozilla.org/en-US/docs/Web/JavaScript/Closures

//未完待续,懒癌犯了剩下的下次补...
//接下来是每周最开心的游戏时间,仁王继续落命中...

相关文章

  • 浅析JS闭包(Closure)与函数的柯里化(Currying)

    先上版图 1、JS闭包 闭包在程序界是一个很抽象的概念,以至于被人称为编程界的哈姆雷特,我们先来看看MDN对其的解...

  • [译]JavaScript中的函数柯里化

    原文 Currying in JS 函数柯里化 函数柯里化以Haskell Brooks Curry命名,柯里化是...

  • Swift需要掌握的几个要点

    函数式编程思想实用栗子: Currying(柯里化)书写方式. => 对方法进行变形, 便于重构与精简代码. 闭包...

  • 函数柯里化

    函数柯里化(currying) 我们假设在查看本文档前,您已经有了一定的js基础,并对高阶函数,闭包,call&&...

  • JS_函数柯里化

    JS_函数柯里化 与函数绑定密切相关的主体是函数柯里化(function currying),它用于创建已经设置好...

  • php之闭包函数(Closure)

    php闭包函数(Closure) JS闭包 js和php闭包使用和区别

  • js柯里化

    标签: js柯里化 js柯里化 柯里化是什么在计算机科学中,柯里化(Currying)是把接受多个参数的函数变换成...

  • JS柯里化

    柯里化简介 js柯里化(currying)又译为卡瑞化或加里化,是把接受多个参数的函数,变为可接受多次调用的函数,...

  • 函数的柯里化和反柯里化

    一 柯里化(currying) 柯里化(currying)又称部分求值。一个currying的函数首先会接受一些参...

  • 闭包

    关键词:闭包(closure) 概念:闭包就是能够读取其他函数内部变量的函数,对于js,闭包就是将函数内部和函数外...

网友评论

      本文标题:浅析JS闭包(Closure)与函数的柯里化(Currying)

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