普通英语中的javascript闭包和副作用?(分别)

Javascript closures and side effects in plain English? (separately)

我一直在读一些JavaScript书籍,我经常听说闭包和副作用。出于某种原因,我不明白它们到底是什么。有人能用简单的英语加上例子向我解释一下它们是什么吗?(当你向一个有图形设计师编程水平的人解释时)。


侧面效应是简单的概念。一个"纯函数"是一个函数,它的输入值被映射到一个输出值function plus(x, y) { return x + y; }。一个"侧面效应"是任何其他效应,而不是回报价值。SO,for instance:

ZZU1

具有增强警报对话框(并要求用户相互作用)的侧面效应。每一个代码函数都有一些副作用(它们全部消耗的记忆和时间,如果没有自己的话),但当人们谈论侧面效应时,它们往往与Either IO(如上面的Alert Dialog)或国家的写作有关,而国家的写作则超越了执行期间。

对侧面效应的挑战是,它们使功能难以实现和成功。(这是一个很容易实现的功能,它关闭到"纯粹的功能",因为它们倾向于"做一件好事")


带有副作用的函数除了返回一个值之外还可以做其他事情(尽管它们也可以这样做)。如果可以用这些参数的值替换给定参数的所有函数调用,并且程序具有相同的行为,则不会有副作用。这要求函数总是为给定的参数返回相同的值。

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

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

1
2
3
4
5
6
7
8
9
10
// 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;
}


副作用:

思考一连串的一面效应For example:

Classic example of a side effect:

1
2
var i = 1;
var j = i++;

侧面效应发生在这里发生了什么事,从1到3另一个词中,两件事的发生和侧面效应是i变成2。

封锁:

视觉化链接如此:<><><>。想象一下,这链接的名字叫角色链。然后想象一下,所有这些链接连接对象都是这样的:<>object<>object<>object>object<。Now,keep in mind the following:

(1)All scope chains begin with the global object.

当一个函数被定义时,一个角色链被保持。

(3)当一个函数被引用时,它创建了一个新的对象并添加到该范围链。

Now,please look at the following example:

1
2
3
4
5
function counter () { // define counter
                   var count = 0;
                   return function () { return count + 1;}; // define anonymous function
                   };
var count = counter(); // invoke counter

在这一例子中,当counter()被定义时,计数器链就像这样:<>Global Object<。然后,当counter()被引用时,镜头链看起来像这样:<>global object<>counter object<。在计数器内的无名称函数(称为匿名函数)被定义和引用。The scope chain for the anonymous function once invoked looks like this:<>global object<>counter object<>anonymous function object<>

这里是封闭部分。如果你注意到,匿名函数是使用变量count来确定的。原因在于匿名函数可以在其范围链中访问任何确定的变量。This is what a closure is,a function along with references to any variables in its stored scope chain.

然而,在上面的例子中,一旦函数返回,在援引时创建的对象就被揭示出来,因此实际上没有点。Now look at the following:

1
2
3
4
5
6
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。保存一个关于整个范围链的参考资料,而不被公开。In other words the variable count stores the scope chain like this:<>global object<>counter object<>anonymous function object<。这是封闭的力量,你可以拿一个参数链,并称它为:count()


我不熟悉JavaScript,不会尝试谈论闭包。然而,我对javascript的新认识使我非常了解如何使用在我的常规编程语言(erlang)中不可能实现的副作用。

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

1
2
3
function myFunction() {
    document.getElementById("demo").innerHTML ="Paragraph changed.";
}

这里没有输入参数或返回值,而是由于文档的内容在函数的作用域内是全局的,所以文档的内容会发生更改。例如,如果您要在Erlang中编写此文档,则文档将作为参数传入,并返回新的文档状态。一个阅读呼叫程序的人会看到一个文件被传入,一个修改过的文件被返回。

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


例子

1
2
3
4
5
6
7
8
9
10
function outer() {
    var outerVar;

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

当外部()死亡,函数函数()连续生存和使用