打破封闭,向外行解释

时间:2013-04-18 18:43:20

标签: javascript closures

我有这个,它有效:

myObject.myFunction = (function() {
    var closure = 0;

    return function(value) {
        if (arguments.length) {
            closure = value;
        } else {
            return closure;
        }
    }
})();

它同时充当getter和setter,因此调用myFunction(3.14)将设置闭包,调用myFunction()将获得闭包的值。

问:我可以把它分成一个更罗嗦的例子(没有荒谬)吗?我想做的是这样的事情:

myObject.myFunction1 = myFunction2;
myObject.myFunction1();

function myFunction2() {
    var closure = 0;

    return function(value) {
        if (arguments.length) {
            closure = value;
        } else {
            return closure;
        }
    }
}

我只是试图将JavaScript分解成尽可能小的块,以便我的学生可以集中注意力。

编辑1:

哦等等:我根本不需要myFunction2。

5 个答案:

答案 0 :(得分:2)

您是否只是在寻找解释闭包的最简单方法:

function closure() {
    var privateData = "I'm hidden!";

    return {
        get: function () {
            return privateData;
        },
        set: function (arg) {
            privateData = arg;
        }
    };
}

var privateDataAccess = closure();

console.log(typeof (privateData)); // logs undefined -- privateData is out of scope
console.log(privateDataAccess.get()); // logs "I'm hidden!"
privateDataAccess.set("Now you changed me!");
console.log(privateDataAccess.get()); // logs "Now you changed me!"

这可能就像我想的那样简单: - )

答案 1 :(得分:1)

在第一个示例中,您将内部函数分配给属性“myFunction”。

在第二个示例中,您将外部函数分配给属性“myfunction2”。

这会导致不同的行为,因为第一个示例使用立即调用的函数表达式,其中第二个示例将名为“myFunction2”的声明函数指定给“myFunction1”。为了调用内部函数,你实际上必须做这样的事情。

myObject.myFunction1 = myFunction2;
var myFunction3 = myObject.myFunction1();
myFunction3();

myObject.myFunction1 = myFunction2();
myObject.myFunction1();

答案 2 :(得分:1)

如果我了解你,myObject.myFunction1 = myFunction2();应该有用。

但是,对于简单的getter和setter,我真的没有看到使用该模式的任何优点。您只能从getter / setter内部访问“闭包”变量,而该函数只是简单地设置其值(不转换它)。我的意思是,直接在对象上使用常规属性而不是函数也可以实现同样的目的。


现在我更加关注你正在寻找一种更好的解释闭包的方法。您可以为变量和函数使用有意义的,准确的名称,并添加注释。根据您的代码,这是一个建议:

function createClosure() {
    // Only the function returned below can see the secret
    var secret = 0;
    return function(value) {
        // If anything was passed, change secret (returns undefined)
        if (arguments.length) {
            secret = value;
        // Nothing was passed, return secret
        } else {
            return secret;
        }

    }
}

// Create a function that enables access to the secret
var closure = createClosure();

// Use it to read the secret
console.log('the closure holds the secret: ' + closure());

// Use it to change the secret
closure(10);

// Read it again to check
console.log('the secret now holds ' + closure());

答案 3 :(得分:0)

我认为这就是我要找的东西:

function ConjunctionJunction() {
    var myClosure = 0;

    return function(myValue) {
        if (arguments.length) {
            myClosure = myValue;
        } else {
            return myClosure;
        }
    }
};
myObject = new Object();
myObject.myFunction = ConjunctionJunction(); // This creates a function and assigns it to the variable myObject.myFunction
myObject.myFunction(3.14); // This calls the newly created function as a setter
var x = myObject.myFunction(); // This calls it as a getter, which returns a value.
log(x);

答案 4 :(得分:0)

不,等等。我想这就是我在寻找的东西。这可能就是这样:

myObject = new Object();

;(function($, window, undefined) {
    var Variables = {};

    myObject.myFunction = function(argValue) {
        if (arguments.length) {
            Variables.myValue = argValue;
        } else {
            return Variables.myValue;
        }
    }
})(jQuery, window);


myObject.myFunction(3.14);
var x = myObject.myFunction();
log(x);