use*_*715 29 javascript functional-programming serverside-javascript node.js underscore.js
我已经在聊天应用程序上使用node.js了一段时间(我知道,非常原创,但我认为这是一个很好的学习项目).Underscore.js提供了许多看起来很有趣的函数式编程概念,所以我想了解如何设置JavaScript中的函数式程序.
根据我对函数式编程的理解(这可能是错误的),整个想法是避免副作用,这些副作用基本上都有一个函数来更新函数之外的另一个变量,所以像
var external;
function foo() {
external = 'bar';
}
foo();
Run Code Online (Sandbox Code Playgroud)
会产生副作用,对吗?因此,作为一般规则,您希望避免在全局范围内扰乱变量.
好的,那么当你处理对象时它是如何工作的呢?例如,很多时候,我将有一个构造函数和初始化对象的init方法,如下所示:
var Foo = function(initVars) {
this.init(initVars);
}
Foo.prototype.init = function(initVars) {
this.bar1 = initVars['bar1'];
this.bar2 = initVars['bar2'];
//....
}
var myFoo = new Foo({'bar1': '1', 'bar2': '2'});
Run Code Online (Sandbox Code Playgroud)
所以我的init方法是故意造成副作用,但是处理相同情况的功能方法是什么?
此外,如果有人可以指向我尝试尽可能功能的程序的Python或JavaScript源代码,那也将非常感激.我觉得我接近"得到它",但我只是不在那里.主要是我对函数式编程如何与传统的OOP类概念一起工作感兴趣(或者如果出现这种情况的话,可以将其用于不同的东西).
Bri*_*nna 30
你应该读这个问题:
有很多有用的链接,包括:
现在,对我而言.很多人误解了JavaScript,可能是因为它的语法看起来像大多数其他编程语言(Lisp/Haskell/OCaml看起来完全不同).JavaScript 不是面向对象的,它实际上是一种基于原型的语言.它没有类或经典继承,因此不应该真正与Java或C++进行比较.
与Lisp相比,JavaScript可以更好; 它有闭包和一流的功能.使用它们可以创建其他函数式编程技术,例如部分应用程序(currying).
让我们举个例子(使用sys.putsnode.js):
var external;
function foo() {
external = Math.random() * 1000;
}
foo();
sys.puts(external);
Run Code Online (Sandbox Code Playgroud)
为了消除全局副作用,我们可以将其包装在一个闭包中:
(function() {
var external;
function foo() {
external = Math.random() * 1000;
}
foo();
sys.puts(external);
})();
Run Code Online (Sandbox Code Playgroud)
请注意,我们实际上无法在范围之外external或foo之外执行任何操作.他们完全被自己的封闭所包裹,不可触碰.
现在,摆脱external副作用:
(function() {
function foo() {
return Math.random() * 1000;
}
sys.puts(foo());
})();
Run Code Online (Sandbox Code Playgroud)
最后,这个例子不是纯粹的功能,因为它不可能.使用随机数从全局状态读取(获取种子)并打印到控制台是一种副作用.
我还想指出,将函数式编程与对象混合完全没问题.以此为例:
var Square = function(x, y, w, h) {
this.x = x;
this.y = y;
this.w = w;
this.h = h;
};
function getArea(square) {
return square.w * square.h;
}
function sum(values) {
var total = 0;
values.forEach(function(value) {
total += value;
});
return total;
}
sys.puts(sum([new Square(0, 0, 10, 10), new Square(5, 2, 30, 50), new Square(100, 40, 20, 19)].map(function(square) {
return getArea(square);
})));
Run Code Online (Sandbox Code Playgroud)
如您所见,使用函数式语言中的对象可以很好.有些Lisps甚至还有一些称为属性列表的东西,它们可以被认为是对象.
在功能样式中使用对象的真正技巧是确保您不依赖于它们的副作用,而是将它们视为不可变的.一种简单的方法是,只要您想要更改属性,只需使用新的详细信息创建一个新对象并将其传递给另一个(这是Clojure和Haskell中经常使用的方法).
我坚信功能方面在JavaScript中非常有用,但最终,你应该使用任何使代码更具可读性和适合你的方法.
您必须了解函数式编程和面向对象编程在某种程度上是相互对立的.它既不可能是纯功能的,也不是纯粹的面向对象的.
功能编程就是无状态计算.面向对象编程完全是关于状态转换.(Paraphasing 此,希望不会太严重)
JavaScript更面向对象而不是功能.这意味着如果你想以纯粹的功能性风格进行编程,你必须放弃大部分语言.特别是所有面向对象的部分.
如果你愿意更加务实,那么你可以使用纯粹功能性世界的一些灵感.
我尝试遵守以下规则:
执行计算的函数不应改变状态.并且改变状态的函数不应该执行计算.此外,改变状态的函数应该尽可能少地改变状态.目标是拥有许多只做一件事的小功能.然后,如果你需要做大事,你可以编写一些小函数来完成你需要的工作.
遵循以下规则可以获得许多好处:
易于重用.函数越长越复杂,它也越专业化,因此它可以重用的可能性越小.相反的含义是,较短的函数往往更通用,因此更容易重用.
代码的可靠性.如果代码不太复杂,则更容易推理代码的正确性.
当它们只做一件事时,更容易测试功能.这样就可以减少要测试的特殊情况.
更新:
来自评论的建议.
更新2:
添加了一些有用的链接
| 归档时间: |
|
| 查看次数: |
5200 次 |
| 最近记录: |