javascript 함수형 프로그래밍_javascript 기술에 대한 심층 토론
1 2 |
|
함수형 프로그래밍은 문제를 일련의 함수로 나누는 것입니다. 일반적으로 함수는 서로 연결되고, 서로 중첩되고, 앞뒤로 전달되며 일류 시민으로 처리됩니다. jQuery 또는 Node.js와 같은 프레임워크를 사용해 본 적이 있다면 아마도 이러한 기술 중 일부를 깨닫지 못한 채 사용했을 것입니다.
Javascript에 대한 약간의 당혹감으로 시작합니다.
일반 객체에 할당할 값 목록이 필요하다고 가정해 보겠습니다. 이러한 객체에는 데이터, HTML 객체 등 무엇이든 포함될 수 있습니다.
1 2 3 4 5 6 7 8 9 10 11 |
|
이 코드는 작동하지만 불안정합니다. 모든 코드는 activate() 함수를 전달하지 않고도 객체 값을 변경할 수 있습니다. 그리고 빈 배열 []을 값에 할당하는 것을 잊어버리면 이 코드는 전혀 작동하지 않습니다.
그러나 변수가 함수 내부에서 선언되면 어떤 장난스러운 코드에도 변경되지 않습니다.
1 2 3 4 5 6 7 8 |
|
안돼! 전달된 마지막 개체의 값만 반환됩니다.
첫 번째 함수 안에 함수를 중첩하여 이 문제를 해결할 수도 있습니다.
1 2 3 4 5 6 7 8 |
|
하지만 문제는 여전히 존재하며 이제 누적 함수와 값 변수에 액세스할 수 없습니다.
우리에게 필요한 것은 자기 호출 기능입니다
자체 호출 함수 및 클로저
값 배열을 반환하는 함수 표현식을 반환할 수 있다면 어떨까요? 함수 내에서 선언된 변수는 자체 호출 함수를 포함하여 함수 내의 모든 코드에서 액세스할 수 있습니다.
자체 호출 기능을 사용하면 이전의 당황스러움이 사라집니다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
|
이것은 범위에 관한 것입니다. 변수 값은 외부 코드가 이 함수를 호출하는 경우에도 내부 함수 acquire()에서 볼 수 있습니다. 이것을 폐쇄라고 합니다.
Javascript에서 클로저는 상위 함수의 실행이 완료되더라도 함수가 상위 범위에 액세스할 수 있음을 의미합니다.
클로저는 모든 함수형 언어의 특징입니다. 전통적인 명령형 언어에는 클로저가 없습니다.
고차 함수
자기 호출 함수는 실제로 고차 함수의 한 형태입니다. 고차 함수는 다른 함수를 입력으로 사용하거나 함수를 출력으로 반환하는 함수입니다.
고차 함수는 기존 프로그래밍에서는 일반적이지 않습니다. 명령형 프로그래머는 루프를 사용하여 배열을 반복하는 반면, 기능적 프로그래머는 완전히 다른 접근 방식을 사용합니다. 고차 함수를 사용하면 배열의 각 요소를 함수에 적용하고 새 배열을 반환할 수 있습니다.
이것이 함수형 프로그래밍의 핵심 아이디어입니다. 고차 함수에는 객체와 같은 함수에 논리를 전달하는 기능이 있습니다.
Scheme 및 Haskell과 같은 고전적인 함수가 언어인 것처럼 Javascript에서 함수는 일급 시민으로 취급됩니다. 조금 이상하게 들릴 수도 있지만 실제로 의미하는 바는 함수가 숫자나 객체처럼 기본 유형으로 처리된다는 것입니다. 숫자와 객체를 앞뒤로 전달할 수 있다면 함수도 마찬가지입니다.
오셔서 직접 확인해 보세요. 이제 이전 섹션의 ValueAccumulator() 함수를 고차 함수와 함께 사용하세요.
// forEach()를 사용하여 배열을 반복하고 각 요소에 대해 콜백 함수 accumulator2
를 호출합니다.
var accumulator2 = ValueAccumulator();
var object = [obj1, obj2, obj3]; // 이 배열은 매우 클 수 있습니다
object.forEach(accumulator2);
console.log(accumulator2());
순수기능
순수 함수에서 반환되는 계산 결과는 전달된 매개변수에만 관련됩니다. 여기서는 외부 변수와 전역 상태가 사용되지 않으며 부작용도 없습니다. 즉, 입력으로 전달된 변수는 변경할 수 없습니다. 따라서 순수함수에서 반환된 값만 프로그램에서 사용할 수 있다.
수학적 함수를 사용하여 간단한 예를 들어보세요. Math.sqrt(4)는 항상 2를 반환하고 설정이나 상태와 같은 숨겨진 정보를 사용하지 않으며 부작용을 일으키지 않습니다.
순수함수는 입력과 출력의 관계인 수학적 '함수'를 진정한 해석으로 표현한 것입니다. 그들의 아이디어는 간단하고 재사용하기 쉽습니다. 순수 함수는 완전히 독립적이므로 반복해서 사용하는 데 더 적합합니다.
불순 함수와 순수 함수를 비교하는 예입니다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
|
부적절한 함수는 창 객체의 상태에 의존하여 너비와 높이를 계산하는 반면, 자급자족형 순수 함수는 이러한 값을 매개변수로 전달해야 합니다. 실제로 정보를 어디에서나 인쇄할 수 있으므로 이 기능이 더욱 다양해집니다.
불순한 함수는 요소를 반환하는 대신 요소 추가를 내부적으로 구현하므로 더 쉬운 선택처럼 보입니다. 값을 반환하는 순수 함수 printSomewhere()는 다른 함수형 프로그래밍 기술과 결합될 때 더 나은 성능을 발휘합니다.
1 2 3 4 5 6 |
|
当一个函数是纯的,也就是不依赖于状态和环境,我们就不用管它实际是什么时候被计算出来。 后面的惰性求值将讲到这个。
匿名函数
把函数作为头等对象的另一个好处是匿名函数。
就像名字暗示的那样,匿名函数就是没有名字的函数。实际不止这些。它允许了在现场定义临时逻辑的能力。 通常这带来的好处就是方便:如果一个函数只用一次,没有必要给它浪费一个变量名。
下面是一些匿名函数的例子:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
|
下面是匿名函数和高阶函数配合使用的例子
1 2 3 4 5 6 7 8 9 10 11 12 13 |
|
这里返回的那个函数不需要命名,它可以在powersOf()函数外的任何地方使用,这就是匿名函数。
还记得累加器的那个函数吗?它可以用匿名函数重写
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 |
|
真棒!一个高阶匿名纯函数。我们怎么这么幸运?实际上还不止这些,这里面还有个自执行的结构, (function(){...})();。函数后面跟的那个括号可以让函数立即执行。在上面的例子里, 给外面values赋的值是函数执行的结果。
匿名函数不仅仅是语法糖,他们是lambda演算的化身。请听我说下去…… lambda演算早在计算机和计算机语言被发明的很久以前就出现了。它只是个研究函数的数学概念。 非同寻常的是,尽管它只定义了三种表达式:变量引用,函数调用和匿名函数,但它被发现是图灵完整的。 如今,lambda演算处于所有函数式语言的核心,包括javascript。
由于这个原因,匿名函数往往被称作lambda表达式。
匿名函数也有一个缺点,那就是他们在调用栈中难以被识别,这会对调试造成一些困难。要小心使用匿名函数。
方法链
在Javascript中,把方法链在一起很常见。如果你使用过jQuery,你应该用过这种技巧。它有时也被叫做“建造者模式”。
这种技术用于简化多个函数依次应用于一个对象的代码。
1 2 3 4 5 6 7 8 9 10 |
|
这只有在函数是目标对象所拥有的方法时才有效。如果你要创建自己的函数,比如要把两个数组zip到一起, 你必须把它声明为Array.prototype对象的成员.看一下下面的代码片段:
Array.prototype.zip = function(arr2) {
// ...
}
这样我们就可以写成下面的样子
arr.zip([11,12,13,14).map(function(n){return n*2});
// Output: 2, 22, 4, 24, 6, 26, 8, 28
递归
递归应该是最著名的函数式编程技术。就是一个函数调用它自己。
当函数调用自己,有时奇怪的事情就发生了。它的表现即是一个循环,多次执行同样的代码,也是一个函数栈。
使用递归函数时必须十分小心地避免无限循环(这里应该说是无限递归)。就像循环一样,必须有个停止条件。 这叫做基准情形(base case)。
下面有个例子
1 2 3 4 5 6 7 8 9 10 |
|
译注:原文中的代码有误,递归情形的函数调用缺少return,导致函数执行得最后没有结果。这里已经纠正。
递归和循环可以相互转换。但是递归算法往往更合适,甚至是必要的,因为有些情形用循环很费劲。
一个明显的例子就是遍历树。
1 2 3 4 5 6 7 8 9 |
|
分而治之
递归不只是代替for和while循环的有趣的方式。有个叫分而治之的算法,它递归地把问题拆分成更小的情形, 直到小到可以解决。
历史上有个欧几里得算法用于找出两个数的最大公分母
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
|
理论上来说,分而治之很牛逼,但是现实中有用吗?当然!用Javascript的函数对数组排序不是很好, 它不但替换了原数组,也就是说数据不是不变的,并且它还不够可靠、灵活。通过分而治之,我们可以做得更好。
全部的实现代码大概要40行,这里只展示伪代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
|
译注:关于用分而治之的思路进行排序的一个更好的例子是快排,使用Javascript也只有13行代码。 具体请参考我以前的博文 《优雅的函数式编程语言》
惰性求值
惰性求值,也叫做非严格求值,它会按需调用并推迟执行,它是一种直到需要时才计算函数结果的求值策略, 这对函数式编程特别有用。比如有行代码是 x = func(),调用这个func()函数得到的返回值会赋值给x。 但是x等于什么一开始并不重要,直到需要用到x的时候。等到需要用x的时候才调用func()就是惰性求值。
这一策略可以让性能明显增强,特别是当使用方法链和数组这些函数式程序员最喜爱的程序流技术的时候。 惰性求值让人兴奋的一个优点是让无限序列成为可能。因为在它实在无法继续延迟之前,什么都不需要被真正计算出来。 它可以是这个样子:
1 2 3 |
|
这为很多可能性敞开了大门,比如异步执行、并行计算、组合,这只列举了一点。
然而,还有个问题,Javascript本身并不支持惰性求值,也就是说存在让Javascript模拟惰性求值的函数库, 这是第三章的主题。

핫 AI 도구

Undresser.AI Undress
사실적인 누드 사진을 만들기 위한 AI 기반 앱

AI Clothes Remover
사진에서 옷을 제거하는 온라인 AI 도구입니다.

Undress AI Tool
무료로 이미지를 벗다

Clothoff.io
AI 옷 제거제

AI Hentai Generator
AI Hentai를 무료로 생성하십시오.

인기 기사

뜨거운 도구

메모장++7.3.1
사용하기 쉬운 무료 코드 편집기

SublimeText3 중국어 버전
중국어 버전, 사용하기 매우 쉽습니다.

스튜디오 13.0.1 보내기
강력한 PHP 통합 개발 환경

드림위버 CS6
시각적 웹 개발 도구

SublimeText3 Mac 버전
신 수준의 코드 편집 소프트웨어(SublimeText3)

뜨거운 주제











JavaScript 문자열 교체 방법 및 FAQ에 대한 자세한 설명 이 기사는 JavaScript에서 문자열 문자를 대체하는 두 가지 방법 인 내부 JavaScript 코드와 웹 페이지의 내부 HTML을 탐색합니다. JavaScript 코드 내부의 문자열을 교체하십시오 가장 직접적인 방법은 대체 () 메소드를 사용하는 것입니다. str = str.replace ( "find", "replace"); 이 메소드는 첫 번째 일치 만 대체합니다. 모든 경기를 교체하려면 정규 표현식을 사용하고 전역 플래그 g를 추가하십시오. str = str.replace (/fi

이 튜토리얼은 사용자 정의 Google 검색 API를 블로그 또는 웹 사이트에 통합하는 방법을 보여 주며 표준 WordPress 테마 검색 기능보다보다 세련된 검색 경험을 제공합니다. 놀랍게도 쉽습니다! 검색을 Y로 제한 할 수 있습니다

그래서 여기 당신은 Ajax라는이 일에 대해 배울 준비가되어 있습니다. 그러나 정확히 무엇입니까? Ajax라는 용어는 역동적이고 대화식 웹 컨텐츠를 만드는 데 사용되는 느슨한 기술 그룹을 나타냅니다. 원래 Jesse J에 의해 만들어진 Ajax라는 용어

이 기사 시리즈는 2017 년 중반에 최신 정보와 새로운 예제로 다시 작성되었습니다. 이 JSON 예에서는 JSON 형식을 사용하여 파일에 간단한 값을 저장하는 방법을 살펴 봅니다. 키 값 쌍 표기법을 사용하여 모든 종류를 저장할 수 있습니다.

손쉬운 웹 페이지 레이아웃에 대한 jQuery 활용 : 8 에센셜 플러그인 jQuery는 웹 페이지 레이아웃을 크게 단순화합니다. 이 기사는 프로세스를 간소화하는 8 개의 강력한 JQuery 플러그인을 강조합니다. 특히 수동 웹 사이트 생성에 유용합니다.

핵심 포인트 JavaScript에서는 일반적으로 메소드를 "소유"하는 객체를 말하지만 함수가 호출되는 방식에 따라 다릅니다. 현재 객체가 없으면 글로벌 객체를 나타냅니다. 웹 브라우저에서는 창으로 표시됩니다. 함수를 호출 할 때 이것은 전역 객체를 유지하지만 객체 생성자 또는 그 메소드를 호출 할 때는 객체의 인스턴스를 나타냅니다. call (), apply () 및 bind ()와 같은 메소드를 사용 하여이 컨텍스트를 변경할 수 있습니다. 이 방법은 주어진이 값과 매개 변수를 사용하여 함수를 호출합니다. JavaScript는 훌륭한 프로그래밍 언어입니다. 몇 년 전,이 문장은있었습니다

JQuery는 훌륭한 JavaScript 프레임 워크입니다. 그러나 어떤 도서관과 마찬가지로, 때로는 진행 상황을 발견하기 위해 후드 아래로 들어가야합니다. 아마도 버그를 추적하거나 jQuery가 특정 UI를 달성하는 방법에 대해 궁금한 점이 있기 때문일 것입니다.

이 게시물은 Android, BlackBerry 및 iPhone 앱 개발을위한 유용한 치트 시트, 참조 안내서, 빠른 레시피 및 코드 스 니펫을 컴파일합니다. 개발자가 없어서는 안됩니다! 터치 제스처 참조 안내서 (PDF) Desig를위한 귀중한 자원
