什么是“关闭"? [英] What is a 'Closure'?

查看:23
本文介绍了什么是“关闭"?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我问了一个关于 Currying 的问题,有人提到了闭包.什么是闭包?它与柯里化有何关系?

I asked a question about Currying and closures were mentioned. What is a closure? How does it relate to currying?

推荐答案

变量作用域

当你声明一个局部变量时,该变量有一个作用域.通常,局部变量只存在于声明它们的块或函数中.

Variable scope

When you declare a local variable, that variable has a scope. Generally, local variables exist only within the block or function in which you declare them.

function() {
  var a = 1;
  console.log(a); // works
}    
console.log(a); // fails

如果我尝试访问局部变量,大多数语言会在当前范围内查找它,然后通过父范围向上查找,直到到达根范围.

If I try to access a local variable, most languages will look for it in the current scope, then up through the parent scopes until they reach the root scope.

var a = 1;
function() {
  console.log(a); // works
}    
console.log(a); // works

当一个块或函数用完后,它的局部变量就不再需要了,而且通常会耗尽内存.

When a block or function is done with, its local variables are no longer needed and are usually blown out of memory.

这就是我们通常期望的工作方式.

This is how we normally expect things to work.

闭包是一个持久作用域,即使在代码执行移出该块之后,它仍然保留局部变量.支持闭包的语言(例如 JavaScript、Swift 和 Ruby)将允许您保留对作用域(包括其父作用域)的引用,即使在声明这些变量的块已完成执行之后,只要您保留引用到某个块或函数.

A closure is a persistent scope which holds on to local variables even after the code execution has moved out of that block. Languages which support closure (such as JavaScript, Swift, and Ruby) will allow you to keep a reference to a scope (including its parent scopes), even after the block in which those variables were declared has finished executing, provided you keep a reference to that block or function somewhere.

作用域对象及其所有局部变量都与函数相关联,并且只要该函数持续存在,就会持续存在.

The scope object and all its local variables are tied to the function and will persist as long as that function persists.

这给了我们函数可移植性.我们可以期待在函数第一次定义时在作用域内的任何变量在我们以后调用函数时仍然在作用域内,即使我们在完全不同的上下文中调用函数.

This gives us function portability. We can expect any variables that were in scope when the function was first defined to still be in scope when we later call the function, even if we call the function in a completely different context.

这是一个非常简单的 JavaScript 示例,说明了这一点:

Here's a really simple example in JavaScript that illustrates the point:

outer = function() {
  var a = 1;
  var inner = function() {
    console.log(a);
  }
  return inner; // this returns a function
}

var fnc = outer(); // execute outer to get inner 
fnc();

这里我在函数中定义了一个函数.内部函数可以访问所有外部函数的局部变量,包括 a.变量 a 在内部函数的范围内.

Here I have defined a function within a function. The inner function gains access to all the outer function's local variables, including a. The variable a is in scope for the inner function.

通常当一个函数退出时,它的所有局部变量都会被吹走.然而,如果我们返回内部函数并将其分配给一个变量 fnc 以便它在 outer 退出后仍然存在,所有在作用域内的变量inner 也被定义为持久化.变量 a 已经被关闭——它在一个闭包内.

Normally when a function exits, all its local variables are blown away. However, if we return the inner function and assign it to a variable fnc so that it persists after outer has exited, all of the variables that were in scope when inner was defined also persist. The variable a has been closed over -- it is within a closure.

注意变量 afnc 是完全私有的.这是一种在 JavaScript 等函数式编程语言中创建私有变量的方法.

Note that the variable a is totally private to fnc. This is a way of creating private variables in a functional programming language such as JavaScript.

您可能会猜到,当我调用 fnc() 时,它会打印 a 的值,即1".

As you might be able to guess, when I call fnc() it prints the value of a, which is "1".

在没有闭包的语言中,当函数 outer 退出时,变量 a 会被垃圾收集并丢弃.调用 fnc 会抛出错误,因为 a 不再存在.

In a language without closure, the variable a would have been garbage collected and thrown away when the function outer exited. Calling fnc would have thrown an error because a no longer exists.

在 JavaScript 中,变量 a 会持续存在,因为变量作用域是在函数第一次声明时创建的,并且只要函数继续存在就会持续存在.

In JavaScript, the variable a persists because the variable scope is created when the function is first declared and persists for as long as the function continues to exist.

a属于outer的范围.inner 的作用域有一个指向 outer 作用域的父指针.fnc 是一个指向 inner 的变量.只要 fnc 持续存在,a 就会持续存在.a 在闭包内.

a belongs to the scope of outer. The scope of inner has a parent pointer to the scope of outer. fnc is a variable which points to inner. a persists as long as fnc persists. a is within the closure.

我制作了一个 YouTube 视频,通过一些实际使用示例查看了这段代码.

I made a YouTube video looking at this code with some practical examples of usage.

这篇关于什么是“关闭"?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆