简体   繁体   English

现代闭包 VS 类 Javascript

[英]Closures VS Classes in modern Javascript

For closures which main goal it's to create another functions, I was wondering if in modern javascript, it's better to just use classes in modern javascript.对于主要目标是创建另一个函数的闭包,我想知道在现代 javascript 中,最好只在现代 javascript 中使用类。

// Closure way private counter
const countPlusOne = () => {
    let count = 0;
    return () =>{
        count++;
        console.log(count);
    }
}
let demoAdd = countPlusOne();
demoAdd(); // 1
demoAdd(); // 2
demoAdd(); // 3

To be honest, I never liked the use of closures in that way (but I think they're great for things like middlewares) as are hard to read.老实说,我从来不喜欢以这种方式使用闭包(但我认为它们非常适合中间件之类的东西),因为它们很难阅读。

So, should I refactor closures like the one up, to classes?那么,我是否应该将闭包重构为类? Their behavior seem more analogous to typical Objects from other languages.它们的行为似乎更类似于其他语言中的典型对象。

// Class way private counter
class countPlusClass{
    count = 0;
    add(){
        this.count++;
        console.log(this.count)
    }
}
const demo = new countPlusClass();
demo.add(); // 1
demo.add(); // 2
demo.add(); // 3

Classes are not always better.课程并不总是更好。 It really depends upon the circumstances.这真的取决于具体情况。 Each has their place in your programming toolset.每个在您的编程工具集中都有自己的位置。

A class has the following advantages:一个class有以下优点:

  1. There's defined syntax in the language语言中有定义的语法
  2. You can sub-class a class to extend it您可以子类 class 来扩展它
  3. You can more easily have many properties and many methods.您可以更轻松地拥有许多属性和许多方法。
  4. Methods are automatically non-enumerable and run in strict mode.方法自动不可枚举并以严格模式运行。
  5. The syntax in the code that uses a class somewhat self-describes what is happening since new countPlusClass() makes it clear you're creating an object that will then have methods and probably state. That's not as obvious with the closure you show.使用 class 的代码中的语法在某种程度上自我描述了自new countPlusClass()以来发生的事情,它清楚地表明您正在创建一个 object,然后将具有方法,并且可能具有 state。这对于您显示的闭包并不那么明显。
  6. For object with a lot of methods there's some space-savings benefit to the prototype that a class uses.对于有很多方法的class使用的原型有一些节省空间的好处。
  7. Developer tools will recognize an instance of a class and know how to display it, auto-complete when typing code for it, how to represent it in the debugger, how to use it in error messages, etc...开发人员工具将识别 class 的实例并知道如何显示它、在为其输入代码时自动完成、如何在调试器中表示它、如何在错误消息中使用它等等……

A closure has these advantages:闭包具有以下优点:

  1. The data in the closure is complete private.闭包中的数据是完全私有的。 Nobody can get to it from outside the closure.没有人可以从关闭之外到达它。
  2. In some circumstances, the caller may find it takes less code to use the closure since you make one function call (sometimes passing arguments) and you get back another function that then implements the one thing this is supposed to do (your mention of middleware comes to mind).在某些情况下,调用者可能会发现使用闭包需要更少的代码,因为您进行了一次 function 调用(有时传递参数)并且您返回了另一个 function 然后实现了这应该做的一件事(你提到的中间件来了去提醒)。

So, I'd say that if you want or need or value any of the benefits of the class, then use the class.所以,我想说,如果您想要或需要或重视 class 的任何好处,请使用 class。

If you don't want or need any of the benefits of the class and the simpler interface of the closure meets your needs or if you really need the privacy of the closure, then you can choose the closure.如果您不想要或不需要class的任何好处而闭包更简单的界面满足您的需求或者您确实需要闭包的私密性,那么您可以选择闭包。

I'd say that for a given circumstance, one of these tools may be a better "fit" for the problem at hand.我想说的是,对于给定的情况,其中一种工具可能更“适合”手头的问题。


As has been mentioned in the comments, you can also have factory functions that may be closures (retain private state in a closure) and may return an object with methods and/or properties that can even be an object created by instantiating a class. So, these concepts can all be combined too to get some of the benefits of both.正如评论中提到的,您还可以拥有可能是闭包的工厂函数(在闭包中保留私有 state),并可能返回 object,其方法和/或属性甚至可以是通过实例化 class 创建的 object。所以,这些概念也可以全部结合起来,以获得两者的一些好处。

No, classes aren't always better.不,课程并不总是更好。 They're just different.他们只是不同。 I'd say the main differences are我想说的主要区别是

  • the interface of the thing returned by the constructor/factory function. A class instance has properties and methods, and usually multiple of them, whereas a closure is simply a function that you can call - with a single functionality.构造函数/工厂返回的事物的接口 function。一个 class 实例具有属性和方法,通常有多个,而闭包只是一个 function,您可以调用它 - 具有单一功能。 The syntax to invoke them is different, the extra method name is sometimes superfluous and sometimes beneficial.调用它们的语法不同,额外的方法名称有时是多余的,有时是有益的。
  • In OOP, objects are expected to have an identity and a state. In FP, functions are expected to be pure.在 OOP 中,对象应该有一个标识和一个 state。在 FP 中,函数应该是纯函数。 Sure, you don't need to follow a specific paradigm, and stateless objects are fine as are impure functions (though maybe call them "procedures" then), but keep these conventions in mind when arguing about readability and maintainability.当然,您不需要遵循特定的范例,无状态对象和不纯函数一样都很好(尽管那时可能称它们为“过程”),但在争论可读性和可维护性时请记住这些约定。

So choose wisely.所以明智地选择。 Do you (possibly in the future) need multiple methods?您(可能在将来)需要多种方法吗? Do you encapsulate state? state封装了吗? Then use a class to create objects.然后使用一个class来创建对象。 Do you only need a function to call?只需要一个function就可以打电话吗? Then create a closure.然后创建一个闭包。

A closure has a significant advantage over a class the way you're imagining: with a class, if you use a public class field like you are, any code with access to the instance can modify its value.与您想象的 class 相比,闭包具有显着优势:对于 class,如果您像现在一样使用公共 class 字段,任何有权访问该实例的代码都可以修改其值。 This is usually undesirable - scope should generally be constrained as possible and you don't want the correctness of your class to depend on consumers of the class not modifying it (whether accidentally or deliberately).这通常是不可取的 - scope 通常应尽可能受到限制,并且您不希望 class 的正确性取决于 class 的消费者不修改它(无论是无意还是故意)。

 class countPlusClass{ count = 0; add(){ this.count++; console.log(this.count) } } const demo = new countPlusClass(); demo.add(); // 1 demo.add(); // 2 // some code elsewhere in the codebase that has access to the demo instance: demo.count = 55555; demo.add(); // not 3...

Closures, in contrast, are completely private ( barring strange, exceptional circumstances ).相比之下,闭包是完全私有的(除非出现奇怪的异常情况)。

If you were to use a class, and you wanted to emulate the privacy of closures, make sure to use private class fields instead, so they can't be modified outside the class.如果你要使用 class,并且你想模拟闭包的隐私,请确保使用私有 class 字段,这样它们就不能在 class 之外被修改。

 class countPlusClass{ #count = 0; add(){ this.#count++; console.log(this.#count) } } const demo = new countPlusClass(); demo.add(); // 1 demo.add(); // 2 // some code elsewhere in the codebase that has access to the demo instance // cannot modify the private field demo.count = 55555; demo.add(); // not 3...

As for which is better, a closure-based object or a class?至于哪个更好,基于闭包的 object 还是 class? That's up to each individual developer.这取决于每个开发人员。

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

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