简体   繁体   English

对使用实际关闭方式的怀疑

[英]Doubts About Use of Practical Closure

I'm trying to find out more about closures in Javascript and was going through this: https://developer.mozilla.org/en/JavaScript/Guide/Closures#Practical_closures 我正在尝试查找有关Java闭包的更多信息,并正在经历以下过程: https : //developer.mozilla.org/en/JavaScript/Guide/Closures#Practical_closures

According to this article, by using such a function: 根据本文,通过使用这样的功能:

function makeSizer(size) {  
    return function() {  
        document.body.style.fontSize = size + 'px';  
    };  
}  

var size12 = makeSizer(12);  
var size14 = makeSizer(14);  
var size16 = makeSizer(16); 

We can then make use of such statements to increase/decrease the font-size of text on a page: 然后,我们可以使用这样的语句来增加/减小页面上文本的字体大小:

document.getElementById('size-12').onclick = size12;  
document.getElementById('size-14').onclick = size14; 
document.getElementById('size-16').onclick = size16;

While I understand the concept here - ie size12, size14 and size16 become closures that allow access to the internal function, I can't help but feel that this is unnecessary. 虽然我在这里理解了概念-即size12,size14和size16成为允许访问内部函数的闭包,但我不禁感到这是不必要的。 Isn't it easier to just have: 拥有它不是更容易吗?

function makeSizer(size) {  
    document.body.style.fontSize = size + 'px';  
}   

, and then invoke it with these? ,然后用这些调用它?

document.getElementById('size-12').onclick = makeSizer(12);  
document.getElementById('size-14').onclick = makeSizer(14); 
document.getElementById('size-16').onclick = makeSizer(16);

Can anyone tell me if my thinking is right - or maybe I'm just a novice to Javascript and doesn't understand the advantage to using closure in this scenario, in which case I'll be most glad if you can explain the advantage of doing so. 谁能告诉我我的想法是否正确-也许我只是Java的新手,并且不了解在这种情况下使用闭包的优势,在这种情况下,如果您能解释一下Java的优势,我将非常高兴这样做。

Thanks in advance guys. 在此先感谢大家。

No, you can't do that. 不,你不能那样做。

It's as if you had written: 好像您已经写过:

document.getElementById('size-12').onclick = (function(size) {  
    document.body.style.fontSize = size + 'px';  
})(12);

The function gets immediately invoked , the style will be applied straight away, and no .onclick handler gets registered because the return value of the function is undefined . 该函数将立即被调用 ,样式将立即应用,并且不会注册.onclick处理程序,因为该函数的返回值是undefined

The real point of the example is to show that you can return a function from another function, and that you can then assign that result to an event handler. 该示例的真正目的是表明您可以从另一个函数返回一个函数,然后可以将该结果分配给事件处理程序。


If you had left makeSizer() unmodified then you could assign the handlers as proposed without intermediate variables, ie: 如果未修改makeSizer()则可以按建议分配处理程序,而无需中间变量,即:

document.getElementById('size-12').onclick = makeSizer(12);

but that won't work if you change makeSizer() the way you described. 但是如果您按照描述的方式更改makeSizer()则将无法使用。

It is also less efficient than storing the "sizer" in a variable if you use the same sizer more than once. 如果不止一次使用同一个sizer,它的效率也比将“ sizer”存储在变量中的效率低。

Yes, those variables ( sizeN ) are unnecessary. 是的,这些变量( sizeN )是不必要的。 You can directly assign the result of makeSizer() as handlers, which looks far better. 您可以直接将makeSizer()的结果分配为处理程序,这看起来要好得多。

But, the use of these variables is not the concept of closures. 但是,使用这些变量不是闭包的概念。 The closure in this example is the function makeSizer , which returns a function (even without arguments), which still has access to the size variable. 此示例中的闭包是函数makeSizer ,该函数返回一个函数 (即使没有参数),该函数仍然可以访问size变量。

Though, you need to see the difference between 不过,您需要了解两者之间的区别

function makeSizer(size) {  
    return function resize() {  
        document.body.style.fontSize = size + 'px';  
    };  
}

and

function resize(size) {  
    document.body.style.fontSize = size + 'px';  
}

Executing makeSizer(5) does not do anything, it returns a function that sets the size to the pre-defined size when invoked. 执行makeSizer(5)不会执行任何操作,它会返回一个函数,该函数在调用时将大小设置为预定义的大小。 Instead executing resize(5) does set the size directly. 而是执行resize(5)会直接设置大小。 You can't use the result of the latter function as an event handler. 您不能将后一个函数的结果用作事件处理程序。

For the example you presented, of course closure is not necessary, but I guess it is just to make it simple to present the concept. 对于您提供的示例,当然不需要闭包,但是我想只是为了简单地介绍这个概念。 There are cases though that closure is the best solution to use: think about how to implement a "private" attribute in javascript or when you need curryng to encapsulate arguments (ie, for a callback function). 在某些情况下,闭包是最好的解决方案:考虑如何在javascript中实现“私有”属性,或者何时需要使用curryng封装参数(例如,用于回调函数)。

I hope the following example helps: 希望以下示例对您有所帮助:

var makeSequencer = function() {
    var _count = 0; // not accessible outside this function
    var sequencer = function () {
        return _count++;
    }
    return sequencer;
}

var fnext = makeSequencer();
var v0 = fnext();     // v0 = 0;
var v1 = fnext();     // v1 = 1;
var vz = fnext._count // vz = undefined

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM