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

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

问题描述

我问了一个关于柯里和封闭的问题。
什么是封闭?它与currying有什么关系?

解决方案

变量范围



当你声明一个局部变量,该变量有一个范围。通常局部变量只存在于声明它们的块或函数中。

  function(){
var a = 1;
console.log(a); //作品
}
console.log(a); //失败

如果我尝试访问局部变量,大多数语言都会在当前

  var a = 1;范围,然后通过父范围,直到它们到达根范围。 
函数(){
console.log(a); //作品
}
console.log(a); //作品

当一个块或函数完成时,其局部变量不再需要,并且通常是内存不足而已。



这就是我们通常期望的事情。



闭包是一个持久局部变量作用域



闭包是一个持久作用域,即使在代码执行已经移出该块之后,持久作用域也可以保留局部变量。支持闭包的语言(例如JavaScript,Swift和Ruby)将允许您保持对作用域(包括其父作用域)的引用,即使在声明这些变量的块已经完成执行之后,只要保留对该块或功能在某处。



范围对象及其所有局部变量都与该函数绑定,并且只要该函数持续存在,该对象就会一直存在。



这给了我们函数的可移植性。我们可以预期,当函数首次被定义时,任何在我们稍后调用函数时仍然在范围内的变量,即使我们在完全不同的上下文中调用该函数。

例如



下面是JavaScript中一个非常简单的例子,它说明了这一点: $ b

  outer = function(){
var a = 1;
var inner = function(){
console.log(a);
}
return inner; //这返回一个函数
}

var fnc = outer(); //执行outer获取内部
fnc();

这里我定义了一个函数内的函数。内部函数可以访问所有外部函数的局部变量,包括 a 。变量 a 位于内部函数的作用域内。



通常,当函数退出时,其所有局部变量吹走。但是,如果我们返回内部函数并将其分配给变量 fnc ,以便在 outer 已退出之后它仍然存在,当定义 inner 时,所有在范围内的变量也被保存。变量 a 已被关闭 - 它在一个闭包内。



请注意,变量 a 对于 fnc 是完全私有的。这是一种使用JavaScript等函数式编程语言创建私有变量的方法。



正如您可以猜到的那样,当我调用 fnc ()它输出 a ,即1的值。

在没有闭包的语言中,变量 a 会被垃圾收集并在函数 outer exited。调用fnc会产生一个错误,因为 a 不再存在。



在JavaScript中,变量 a 会持续存在,因为变量作用域是在函数首次声明时创建的,只要函数继续存在,它就会一直存在。



a 属于 outer 的范围。 inner 的范围有一个指向 outer 范围的父指针。 fnc 是一个指向 inner 的变量。只要 fnc 仍然存在, a 就会持续存在。 a 在关闭内。


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.

A closure is a persistent local variable scope

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.

For example

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();

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.

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.

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.

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

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.

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

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.

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

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