>  기사  >  웹 프론트엔드  >  Javascript 함수형 프로그래밍_javascript 기술에 대한 간략한 소개

Javascript 함수형 프로그래밍_javascript 기술에 대한 간략한 소개

WBOY
WBOY원래의
2016-05-16 15:36:551166검색

함수형 프로그래밍은 수학적 순수성과 수수께끼 같은 특성으로 인해 수십 년 동안 컴퓨터 공학 애호가들 사이에서 가장 인기가 높았으며, 데이터 과학자와 박사 과정 지원자들은 컴퓨터 연구실에 묻혀 있었습니다. 그러나 이제는 Python, Julia, Ruby, Clojure 및 Javascript와 같은 현대 언어 덕분에 르네상스를 경험하고 있습니다.

자바스크립트를 말씀하시는 건가요? 이 웹 스크립팅 언어? 좋아요!

자바스크립트는 오랫동안 사라지지 않은 중요한 기술임이 입증되었습니다. 이는 주로 backbone.js, jQuery, Dojo, underscore.js 등과 같이 확장하는 일부 프레임워크 및 라이브러리로 인해 다시 태어날 수 있는 기능 때문입니다. 이는 함수형 프로그래밍 언어로서의 Javascript의 진정한 정체성과 직접적인 관련이 있습니다. Javascript의 함수형 프로그래밍에 대한 이해는 중요하며 모든 수준의 프로그래머에게 꽤 오랫동안 유용할 것입니다.

왜요? 함수형 프로그래밍은 매우 강력하고 견고하며 우아합니다. 대규모 데이터 구조에 매우 유용하고 효율적입니다. 클라이언트 측 스크립팅 언어인 Javascript는 DOM을 기능적으로 조작하고, API 응답을 구성하고, 점점 더 복잡해지는 웹사이트를 처리할 때 기타 작업을 완료하는 데 매우 유용합니다.

이 책에서는 함수형 프로그래밍으로 Javascript 웹 애플리케이션을 구축하는 방법, Javascript의 숨겨진 기능을 활용하는 방법, 더욱 강력한 코드를 작성하는 방법 등 Javascript의 함수형 프로그래밍에 대해 알아야 할 모든 것을 배우게 됩니다. 프로그램이 더 작기 때문에 코드를 유지 관리하기가 더 쉽고, 더 빨리 다운로드할 수 있으며, 비용도 더 저렴합니다. 또한 함수형 프로그래밍의 핵심 개념과 이를 Javascript에 적용하는 방법, Javascript를 함수형 언어로 사용할 때 몇 가지 문제를 피하는 방법, Javascript에서 함수형 프로그래밍과 객체지향 프로그래밍을 혼합하는 방법을 배우게 됩니다.

하지만 시작하기 전에 실험을 해보자.

아마도 Javascript에서 함수형 프로그래밍을 소개하는 가장 좋은 방법은 빠른 예제를 사용하는 것입니다. 우리는 Javascript로 몇 가지 작업을 수행할 것입니다. 하나는 전통적인 기본 접근 방식을 사용하고 다른 하나는 함수형 프로그래밍을 사용합니다. 그런 다음 이 두 가지 방법을 비교해 보겠습니다.

신청 - 전자상거래 사이트

리얼리즘을 추구하기 위해 전자상거래 홈페이지, 통신판매 커피빈 회사를 만들 예정입니다. 이 웹사이트에서는 다양한 품질과 가격을 지닌 여러 종류의 커피를 판매합니다.

명령적 방법

먼저 프로그램 작성을 시작합니다. 이 예제를 실용적으로 만들려면 데이터를 보관할 몇 가지 개체를 만들어야 합니다. 필요한 경우 데이터베이스에서 값을 가져올 수 있습니다. 그러나 이제는 정적으로 정의되었다고 가정합니다.

 // create some objects to store the data.
var columbian = {
 name: 'columbian',
 basePrice: 5
};
var frenchRoast = {
 name: 'french roast',
 basePrice: 8
};
var decaf = {
 name: 'decaf',
 basePrice: 6
};
// 我们将使用辅助函数计算价格
// 根据size打印到一个HTML的列表中
function printPrice(coffee, size) {
 if (size == 'small') {
  var price = coffee.basePrice + 2;
 }
 else if (size == 'medium') {
  var price = coffee.basePrice + 4;
 }
 else {
  var price = coffee.basePrice + 6;
 }
 // create the new html list item
 var node = document.createElement("li");
 var label = coffee.name + ' ' + size;
 var textnode = document.createTextNode(label+' price: $'+price);
 node.appendChild(textnode);
 document.getElementById('products').appendChild(node);
}
// 现在我们只需根据咖啡的各种价格和size的组合调用printPrice函数
printPrice(columbian, 'small');
printPrice(columbian, 'medium');
printPrice(columbian, 'large');
printPrice(frenchRoast, 'small');
printPrice(frenchRoast, 'medium');
printPrice(frenchRoast, 'large');
printPrice(decaf, 'small');
printPrice(decaf, 'medium');
printPrice(decaf, 'large');

보시다시피 이 코드는 매우 기본적입니다. 이제 이 세 가지보다 더 많은 종류의 커피가 있다면 어떨까요? 20명, 심지어 50명이라면 어떨까요? 사이즈가 더 많으면 어떻게 되나요? 유기물과 무기물이 있다면 어떨까요? 이렇게 하면 엄청난 양의 코드가 빠르게 추가됩니다!

이 방법을 사용하면 기계가 모든 커피 종류와 크기를 인쇄할 수 있습니다. 이것이 이 명령형 접근 방식을 취하는 데 있어 기본적인 문제입니다.

함수형 프로그래밍

명령형 코드는 문제를 해결하기 위해 수행해야 할 작업을 단계별로 컴퓨터에 알려주는 반면, 함수형 프로그래밍은 문제를 수학적으로 설명하고 나머지는 컴퓨터가 수행하도록 합니다.

보다 기능적인 방법으로 동일한 애플리케이션을 다음과 같이 작성할 수 있습니다.

// 从接口中分解数据和逻辑
var printPrice = function(price, label) {
 var node = document.createElement("li");
 var textnode = document.createTextNode(label+' price: $'+price);
 node.appendChild(textnode);
 document.getElementById('products 2').appendChild(node);
}
// 为每种咖啡创建函数对象
var columbian = function(){
 this.name = 'columbian';
 this.basePrice = 5;
};
var frenchRoast = function(){
 this.name = 'french roast';
 this.basePrice = 8;
};
var decaf = function(){
 this.name = 'decaf';
 this.basePrice = 6;
};
// 为每种size通过字面量创建对象
var small = {
 getPrice: function(){return this.basePrice + 2},
 getLabel: function(){return this.name + ' small'}
};
var medium = {
 getPrice: function(){return this.basePrice + 4},
 getLabel: function(){return this.name + ' medium'}
};
var large = {
 getPrice: function(){return this.basePrice + 6},
 getLabel: function(){return this.name + ' large'}
};
// 将所有咖啡的种类和size放到数组里
var coffeeTypes = [columbian, frenchRoast, decaf];
var coffeeSizes = [small, medium, large];
// 创建由上面内容组成的新对象,并把它们放到一个新数组里
var coffees = coffeeTypes.reduce(function(previous, current) {
 var newCoffee = coffeeSizes.map(function(mixin) {
  // `plusmix`是函数式的minxin, 见第7章
  var newCoffeeObj = plusMixin(current, mixin);
  return new newCoffeeObj();
 });
 return previous.concat(newCoffee);
},[]);
// 现在我们已经定义了如何获得所有咖啡种类和size组合方式的价格,现在可以直接打印它们了
coffees.forEach(function(coffee){
 printPrice(coffee.getPrice(),coffee.getLabel());
});

먼저 명확하게 해야 할 점은 이 코드가 더 모듈화되어 있다는 것입니다. 이제 크기를 추가하거나 커피 유형을 추가하는 것은 다음 코드만큼 간단합니다.

var peruvian = function(){
 this.name = 'peruvian';
 this.basePrice = 11;
};
var extraLarge = {
 getPrice: function(){return this.basePrice + 10},
 getLabel: function(){return this.name + ' extra large'}
};
coffeeTypes.push(Peruvian);
coffeeSizes.push(extraLarge);

咖啡对象的数组和size对象的数组混合(mix)到了一起,也就是他们的方法和成员变量被组合到了一块儿 ——通过一个叫“plusMinxin”的自定义函数(详见第七章)。这些咖啡类型的类(columbian, frenchRoast, decaf)包含了成员变量, 而这些size对象(small, medium, large)包含了获取名称和计算价格的方法。 ”混合”(minxing)这个动作通过一个map操作来起作用,也就是对数组中的每一个成员执行一个纯函数并返回一个新的函数, 然后这些返回的函数被放到了一个reduce函数中被操作,reduce也是一个高阶函数,和map有些像, 只是reduce把数组里的所有元素处理后组合到了一个东西里面。最终,新的数组包含了所有可能的种类和size的组合, 这个数组通过forEach方法遍历,forEach也是一个高阶函数,它会让数组里面每一个对象作为参数执行一遍回调函数。 在这个例子里,这个回调函数是一个匿名函数,它获取这些对象后,以对象的getPrice()和getLabel() 两个方法的返回值作为参数调用printPrice函数。

实际上,我们可以让这个例子更加函数式:去掉coffees变量,并将函数串到一起链式调用,这也是函数式编程的一个小技巧。

coffeeTypes.reduce(function(previous, current) {
 var newCoffee = coffeeSizes.map(function(mixin) {
  // `plusMixin` function for functional mixins, see Ch.7
  var newCoffeeObj = plusMixin(current, mixin);
  return new newCoffeeObj();
 });
 return previous.concat(newCoffee);
},[]).forEach(function(coffee) {
 printPrice(coffee.getPrice(),coffee.getLabel());
});

这样,控制流没有像命令式代码那样从头到尾的顺序进行。在函数式编程里,map函数和其它高阶函数代替了for和while循环, 只有少量关键的代码是在顺序执行。 这使得新接触的人在阅读这样范式的代码有些困难,但是一旦你能够欣赏它,你就会发现这根本没啥难的, 而且这样写看起来更好。

这个例子仅仅是刚开始展露Javascript中函数式编程能做什么。通过这本书,你将会看到更多函数式实现的强悍的例子。

总结

首先,采用函数式风格的优点已经明确了。 其次,不要害怕函数式编程。的确,它往往被认为是编程语言的纯逻辑形式,但是我们不需要理解lambda演算也能够在日常任务中应用它。 实际上,通过把我们的程序拆分成小的片段,它们变得更容易被理解、维护,也更加可靠。 map和reduce函数是Javascript中不太被知道的内建函数,然而我们将要关注它们。

Javascript是一个脚本语言,可交互,易使用,不需要编译。我们甚至不需要下载任何开发软件, 你最喜欢的浏览器就可以作为开发环境的解释器。

感兴趣吗?好,我们开始!

성명:
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.