JavaScript의 플랜트 화살표 함수

23842 단어 javascript
이 문서에서는 JavaScript 템플릿에서 객체를 인스턴스화하는 대체 방법을 설명합니다.더 잘 이해하기 위해 자주 사용하는 ES6 강좌와 비교하는 경우도 있다.

DISCLAIMER
The term factory arrow function is made up as I couldn't succeed in googling for a proper name for that. I avoid calling it factory function because it is an existing term that means a different thing. If you know the correct name for the concept covered in this article, please, share it in a comment - I'd be glad to find out.



이게 시리즈예요.
  • Factory Arrow Functions in JavaScript (part I)
  • Factory Arrow Functions in TypeScript (part II)

  • ES6 과정 검토
    JavaScript의 ES6 클래스가 무엇인지 모르시면 the official MDN article about classes를 읽어 보시기 바랍니다. 그러나 클래스에 대한 충분한 이해와 경험은 본고의 선결 조건이 아닙니다.다음은 간단한 회고입니다.

    Classes are a template for creating objects. They encapsulate data with code to work on that data. Classes in JS are built on prototypes but also have some syntax and semantics that are not shared with ES5 classalike semantics. © MDN
    MDN


    ES6 과정의 주요 특징:
  • 다른 프로그래밍 언어에서 온 개발자에게 익숙한 문법
  • 클래스 표현식이든 클래스 성명이든 상관없이 향상되지 않습니다
  • 클래스에서 성명하는 방법 중this은 클래스
  • 에서 실례화된 현재 대상을 나타낸다
  • 이 종류의 주체는 시종strict mode에서 운행한다
  • 하위 클래스화 사용 가능extends 키워드, 상위 클래스 인용super 키워드
  • 실례는 instanceof 구조 함수로 검사될 수 있다(주의, 여기 용)
  • new 키워드는 하나의 클래스를 실례화하는 데 사용
  • 자바스크립트의 클래스를 보았을 가능성이 높습니다. 왜냐하면 이것은 현재 우리 코드 라이브러리의 흔한 부분이 되었기 때문입니다.다음은 ES6 클래스 선언의 예입니다.
    class Rectangle {
        constructor(length, width) {
            this.length = length
            this.width = width
        }
    
        getArea() {
            return this.length * this.width
        }
    }
    
    const r = new Rectangle(10, 20)
    r.getArea() // 200
    

    플랜트 화살표 기능
    수업이 좋은 점이 많지만 저는 다른 방법을 사용했다는 것을 알게 되었고 여기서 여러분과 나누고 싶습니다.JavaScript에서 매개변수를 적용하고 객체를 반환하는 함수를 작성할 수 있습니다. 이 함수는 클립을 통해 이러한 매개변수에 독점적으로 액세스합니다.
    다음 예는 다음과 같습니다.
    const rectangle = (length, width) => ({
        length,
        width,
        getArea: () => length * width,
    })
    
    const r = rectangle(10, 20)
    r.getArea() // 200
    
    이 예는 몇 가지 빠른 방식을 사용했기 때문에 익숙하지 않은 것처럼 보여도 된다.다음은 우리가 좀 더 전통적인 방식으로 쓰면 어떤 모습일까.
    const rectangle = (length, width) => {
        return {
            length,
            width,
            getArea: () => length * width,
        }
    }
    
    이제 ES6 문법에 비해 이런 방법이 우리에게 가져다 준 쿨한 특성을 개술하고 싶습니다.

    아니오this방법과 대상 생성에서 화살표 함수를 사용할 때 thisundefined 이다.JavaScriptthis는 자신의 행동에 대해 깊이 있게 이해해야 하며, 이를 사용하면 많은 개발자를 오도할 수 있다.의존this과 달리 우리는 매개 변수에 클립을 사용하여 이익을 얻을 수 있다.객체가 매개변수에 액세스할 수 있으므로 이러한 매개변수는 해당 메서드에서 사용할 수 있습니다.
    닫혔기 때문에 안전한 방법으로 추출할 수 있습니다.
    const rectangle = (length, width) => ({
        width,
        length,
        getArea: () => length * width,
    })
    
    const theRectangle = rectangle(10, 20)
    
    const getTheRectangleArea = theRectangle.getArea
    getTheRectangleArea() // 200
    
    주의: 우리는 클래스를 사용하여 안전한 방법을 추출할 수 있다. 예를 들어 Function.prototype.bind를 사용할 수 있지만 공장 화살표 함수를 사용하면 위아래 문장을 잃을까 봐 걱정할 필요가 없다.

    사유재산
    외부에서 함수로 전달되는 매개 변수를 직접 바꾸는 것은 불가능하다.액세스할 수도 없고 변경할 수도 없습니다.매개 변수를 대상 속성에 귀속시키면 접근을 현저하게 허용할 수 있습니다.다음 예제에서는 length를 객체 외부에서 사용할 수 있지만 width는 객체 내부에만 존재하므로 객체 외부에서 액세스할 수 없습니다.
    const rectangle = (length, width) => ({
        length,
        getArea: () => length * width,
    })
    
    const r = rectangle(10, 20)
    r.length // 10
    r.width // undefined
    r.getArea() // 200
    
    무료 보상: 방문 가능한 대상 속성에 다른 값을 지정하더라도 대상 자체는 그 방법에서 파라미터를 사용합니다.객체의 등록 정보는 외부에서 사용되지 않는 경우에만 유효합니다.
    const rectangle = (length, width) => ({
        length,
        width,
        getTotalAreaWith: ({ length: oLength, width: oWidth }) => length * width + oLength * oWidth, // <- This is the cause
    })
    
    const r1 = rectangle(2, 5)
    const r2 = rectangle(3, 6)
    
    r1.getTotalAreaWith(r2) // 28
    
    r1.width = 1000
    r1.getTotalAreaWith(r2) // 28
    
    r2.width = 1000
    r1.getTotalAreaWith(r2) // 3010 <- This is the problem
    
    객체 내부에서 모든 계산을 수행하여 객체 특성 값을 예기치 않게 재지정하는 문제를 방지할 수 있습니다.
    const rectangle = (length, width) => ({
        length,
        width,
        getArea: () => length * width,
        getTotalAreaWith: ({ getArea }) => length * width + getArea(), // <- Now it will work
    })
    
    const r1 = rectangle(2, 5)
    const r2 = rectangle(3, 6)
    
    r1.getTotalAreaWith(r2) // 28
    
    r1.width = 1000
    r1.getTotalAreaWith(r2) // 28
    
    r2.width = 1000
    r1.getTotalAreaWith(r2) // 28
    

    직접 계승과 내부 방법이 호출되지 않았습니다
    이전 예시를 보면 길이에 두 위치의 너비: in getArea 과 in getTotalAreaWith 을 곱한 것을 알 수 있습니다.이것은 우리가 내부this에서 사용할 수 없기 때문이다getArea와 방문getTotalAreaWith. 이것은 모든 것이 가격이 있다는 것을 설명하는 좋은 예이다.
    공장 화살표 함수도 계승을 허용하지 않기 때문에 코드가 중복될 수 있습니다.
    그러나 Google 방법의 익명성 때문에 Google은 단독으로 이러한 방법을 작성하고 대상의 수준 확장을 구축하며 대상 간에 심지어 대상 외부에서 방법을 공유할 수 있습니다.
    간단한 방법은 일부 응용 프로그램을 사용하는 것이다.

    If you are not familiar with the concept of partial application, I suggest you read Kyle Shevlin's article on the topic.


    다음 예에서 나는 multiplyThunk를 만들었는데 그 중 일부는 두 개의 값을 적용했다.그리고 나는 그것을 getArea 방법으로 여러 개의factory arrow 함수에 분배하여 대상을 되돌려주고 한 함수를 사용하여 여러 모양에 적용한다.
    const multiplyThunk = (a, b) => () => a * b
    
    const rectangle = (length, width) => ({
        length,
        width,
        getArea: multiplyThunk(length, width),
    })
    
    const square = (length) => ({
        length,
        getArea: multiplyThunk(length, length),
    })
    
    const circle = (radius) => ({
        radius,
        getArea: multiplyThunk(Math.PI, radius ** 2),
    })
    
    주의: ES6 클래스에서 일부 프로그램을 사용하는 것은 가능하지만, 작은 기회가 있습니다. 보통 thisextends를 더 좋아하기 때문에 이렇게 해야 합니다.

    구성이 상속보다 무겁다
    비록 우리는 공장 화살표 함수를 사용하여 계승할 수 없지만, 우리는 계승이 아니라 조합을 선택할 수 있다. 이것은 우리가 여러 대상에서 동시에 확장할 수 있다는 것을 의미한다.이런 방식을 통해 우리는 특정 상황에서 진정으로 필요한 방법과 속성을 사용하여 경량급 대상을 만들 수 있다.
    참고: ES6 교육 과정도 이렇게 할 수 있습니다.이런 방법은 Mix-in라고 불린다.
    const squarePerimeter = (length) => ({
        getPerimeter: () => 4 * length,
    })
    
    const squareArea = (length) => ({
        getArea: () => length ** 2,
    })
    
    const LengthyShape = (...features) => (length) => ({
        length,
        ...features.reduce(
            (acc, feature) => ({
                ...acc,
                ...feature(length),
            }),
            {},
        ),
    })
    
    const squareWithPerimeter = LengthyShape(squarePerimeter)
    const square = LengthyShape(squarePerimeter, squareArea)
    
    const sp = squareWithPerimeter(5)
    sp.getArea() // Uncaught TypeError: sp.getArea() is not a function
    sp.getPerimeter() // 20
    
    const s = square(5)
    s.getArea() // 25
    s.getPerimeter() // 20
    

    정적 방법
    편의를 위해 정태적인 방법을 모방할 수 있다.정적 방법은 클래스의 방법으로 클래스 자체를 실례화하지 않은 상황에서 호출할 수 있다.클래스가 실례화되었을 때, 그것들도 호출할 수 없습니다. 즉, 실례적인 this 을 통해 그것들을 인용할 수 없습니다.정적 방법은 보통 우리 프로그램의 실용적인 기능에 사용되지만, 다른 응용 분야도 있다.
    공장 화살표 함수를 사용하면 우리는 함수 자체의 속성을 성명하여 정적 방법의 두 법칙을 준수할 수 있다.우리는 같은 방법으로 정적 속성을 성명할 수 있다.
    const Square = (length) => ({
        length,
        getArea: () => length ** 2,
    })
    
    Square.new = Square
    
    const s = Square.new(10) // <- Looks like Rust!
    s.getArea() // 100
    

    결론
    이 문서에서는 JavaScript에서 factory arrow 함수를 사용하는 방법에 대해 설명합니다.In the next one, 나는 TypeScript를 사용하여factory arrow 함수의 사용법을 소개함으로써 이 주제를 확장했다.
    나는 네가 이 책을 좋아하길 바란다.

    좋은 웹페이지 즐겨찾기