Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/443.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
简单英语中的Javascript闭包和副作用?(单独)_Javascript_Closures_Side Effects - Fatal编程技术网

简单英语中的Javascript闭包和副作用?(单独)

简单英语中的Javascript闭包和副作用?(单独),javascript,closures,side-effects,Javascript,Closures,Side Effects,我一直在读一些JavaScript书籍,我总是听说闭包和副作用。由于某种原因,我无法理解它们到底是什么。有人能用简单的英语和例子向我解释一下它们是什么吗?(当您向具有平面设计师编程水平的人解释时)。示例 function outer() { var outerVar; var func = function() { var innerVar ... x = innerVar + outerVar } return

我一直在读一些JavaScript书籍,我总是听说闭包和副作用。由于某种原因,我无法理解它们到底是什么。有人能用简单的英语和例子向我解释一下它们是什么吗?(当您向具有平面设计师编程水平的人解释时)。

示例

function outer() {
    var outerVar;

    var func = function() {
        var innerVar
        ...
        x = innerVar + outerVar
    }
    return func
}

当outer()死亡时,函数func()继续存活,而这种使用实用的副作用是更简单的概念。“纯函数”是将其输入值映射为输出值
函数加(x,y){return x+y;}
的函数。“副作用”是指除返回值以外的任何影响。例如:

function plusWithSideEffects(x, y) {
  alert('This is a side effect'); 
  return x + y;
} 
具有引发警报对话框(并需要用户交互)的副作用。每个代码函数都有一些副作用(它们都会消耗内存和时间,如果没有其他副作用的话),但当人们谈论副作用时,他们通常最关心的是IO(如上面的警报对话框)或写入超出函数执行期的状态

副作用带来的挑战是,它们使函数更难推理和重用。(对尽可能接近“纯函数”的函数进行推理和重用要容易得多,因为它们倾向于“做好一件事”。

副作用:

把副作用想象成同时做两件事。 例如:

副作用的典型示例:

var i = 1;
var j = i++;
副作用发生在
i++
。这里发生的情况是
j
变为1,然后
i
递增并变为2。换句话说,发生了两件事,副作用是
i
变成了2

关闭:

可视化链接链,如下所示:。 假设这个链接链的名称称为范围链。然后想象所有这些链接都像这样将对象连接在一起:objectobjectobject。 现在,请记住以下几点:

function counter () { // define counter
                   var count = 0;
                   function f() { return count + 1;}; // define f
                   return f; // return f
                   };
var count = counter(); // invoke counter
(1) 所有范围链都以全局对象开始

(2) 定义函数时,将存储该函数的作用域链

(3) 调用函数时,它会创建一个新对象并将其添加到范围链中

现在,请看以下示例:

function counter () { // define counter
                   var count = 0;
                   return function () { return count + 1;}; // define anonymous function
                   };
var count = counter(); // invoke counter
在本例中,当定义了
counter()
时,计数器的作用域链如下所示:全局对象。然后,当调用
counter()
时,作用域链如下所示:全局objectcounter对象。然后,定义并调用计数器中没有名称的函数(称为匿名函数)。一旦调用匿名函数,其作用域链如下所示:全局objectcounter objectanonymous function object

这里是收尾部分。如果您注意到,匿名函数使用的是在其外部定义的变量
count
。原因是匿名函数可以访问其作用域链中定义的任何变量。这就是闭包,一个函数以及对其存储范围链中任何变量的引用

然而,在上面的示例中,一旦函数返回,调用时创建的对象将被丢弃,因此实际上没有意义。现在,请看以下内容:

function counter () { // define counter
                   var count = 0;
                   function f() { return count + 1;}; // define f
                   return f; // return f
                   };
var count = counter(); // invoke counter

在本例中,我返回一个名为
f
的函数,并将其分配给变量
count
。现在,变量
count
包含对整个范围链的引用,并且不会被丢弃。换句话说,变量计数存储的范围链如下所示:全局objectcounter objectanonymous function object。这就是闭包的威力,您可以持有对作用域链的引用,并像这样调用它:
count()

具有副作用的函数除了返回值之外还可以执行其他操作(尽管它们也可以这样做)。如果可以将给定参数的所有函数调用替换为这些参数的值,并且程序具有相同的行为,则不会产生任何副作用。这要求函数始终为给定参数返回相同的值

也就是说,假设f(1,2)==12。如果总是可以用
12
替换
f(1,2)
,并且程序的行为方式相同,那么
f
对这些参数没有副作用。另一方面,如果在一个地方
f(1,2)==12
和另一个地方
f(1,2)==13
,则
f
具有副作用。同样,如果程序在将
f(1,2)
替换为12后停止发送电子邮件,则
f
具有副作用。通常,如果
f(x,y)==z
(其中z取决于x和y),并且始终可以使用
z
替换每个
f(x,y)
调用,则
f
没有副作用

一些具有副作用的简单功能:

// doesn't always return the same value
function counter() {
    // globals are bad
    return ++x;
}
// omitting calls to `say` change logging behavior
function say(x) {
    console.log(x);
    return x;
}

我是JavaScript新手,不会尝试谈论闭包。然而,我对JavaScript的新认识让我非常清楚,在我的常用编程语言(Erlang)中,使用副作用是不可能的

副作用似乎是JavaScript中改变状态的常用方法。以w3cschools.com网站上的示例为例:

<script>
function myFunction() {
    document.getElementById("demo").innerHTML = "Paragraph changed.";
}
</script>

函数myFunction(){
document.getElementById(“demo”).innerHTML=“段落已更改。”;
}
这里没有输入参数或返回值,而是更改文档内容,因为它们在函数的作用域中是全局的。例如,如果要在Erlang中编写此文档,则文档将作为参数传入,并返回新文档状态。阅读调用程序的人会看到传入的文档和返回的修改过的文档


看到调用的函数不返回显式的新状态,应该提醒程序员可能会使用副作用。

主要的副作用是从函数内部与外部世界的交互。副作用的一些例子如下:- 应用程式介面呼叫