JavaScript에서 비트 XOR(^) 연산자를 사용하는 방법

현재 엔터티가 있는 Pomodoro 타이머 응용 프로그램에서 작업 중입니다.
프로젝트 카테고리라고 합니다. 다음과 같은 인터페이스가 있습니다.

interface ProjectCategory {
  name: string;
  createdOn: number;
  modifiedOn: number;

  // ... some other fields
}


프로젝트 범주의 유효성을 검사하고 인스턴스화하는 함수를 작성했습니다.
물체. 타임스탬프 유효성 검사와 관련하여 다음 규칙을 구현했습니다.
  • 생성 및 수정 타임스탬프가 둘 다 없는 경우
    현재 타임스탬프.
  • 생성 및 수정 타임스탬프가 모두 있는 경우 다음을 확인하십시오.
    수정 타임스탬프가 생성보다 크거나 같음
    타임 스탬프.
  • 그렇지 않으면 오류가 발생합니다.

  • 코드는 다음과 같습니다.

    function makeProjectCategory( arg: Partial<ProjectCategory>): Readonly<ProjectCategory> {
      const projectCategory: Partial<ProjectCategory> = {};
      // ... timestamps validation
    
      {
        const isCreatedOnPresent = "createdOn" in arg;
        const isModifiedOnPresent = "modifiedOn" in arg;
    
        const isOneTimestampMissing = +isCreatedOnPresent ^ +isModifiedOnPresent;
        // (isCreatedOnPresent && !isModifiedOnPresent) ||
        // (!isCreatedOnPresent && isModifiedOnPresent);
    
        if (isOneTimestampMissing)
          throw new Error(
            `Creation and Modification timestamps must be provided together.`
          );
    
        if (isCreatedOnPresent) {
          // so both timestamps are present
          assertValidTimestamps({
            createdOn: arg.createdOn,
            modifiedOn: arg.modifiedOn,
          });
          // ...
        } else projectCategory.createdOn = projectCategory.modifiedOn = Date.now();
      }
    
      // ... other fields validation
    
      return Object.freeze(projectCategory) as Readonly<ProjectCategory>;
    }
    


    이 코드를 작성하고 나서 유효성 검사 논리가
    XOR 논리 게이트.


    isCreatedOnPresent
    isModifiedOnPresent
    isOneTimestampMissing(?를 던져야 함)


    진실
    진실
    거짓

    거짓
    진실
    진실

    진실
    거짓
    진실

    거짓
    거짓
    거짓


    그래서 다음 스 니펫을 변경했습니다.

    const isOneTimestampMissing =
      (isCreatedOnPresent && !isModifiedOnPresent) ||
      (!isCreatedOnPresent && isModifiedOnPresent);
    


    에게:

    const isOneTimestampMissing = +isCreatedOnPresent ^ +isModifiedOnPresent;
    


    어떻게 작동하는지 설명하겠습니다.

    XOR 논리 게이트의 진리표




    입력 비트 A
    입력 비트 B
    결과 비트


    1
    1
    0

    1
    0
    1

    0
    1
    1

    0
    0
    0


    XOR 연산자(JS의 ^)가 두 비트에 적용되면 다음을 반환합니다.

  • 1 ( true ) 교대하는 경우.

  • 0 ( false ) 동일한 경우.

  • 따라서 다음 스니펫을 실행하면 다음과 같이 표시됩니다.

    console.log(1 ^ 1); // 0
    console.log(1 ^ 0); // 1
    console.log(0 ^ 1); // 1
    console.log(0 ^ 0); // 0
    


    하지만 위의 코드 스니펫에서 10는 단일 비트를 나타내지 않습니다!
    엄밀히 말하면 32비트 숫자입니다. XOR 연산자가 두 개에 적용될 때
    먼저 숫자를 이진 형식으로 변환한 다음
    한 번에 각 비트. 설명하겠습니다.

    #1:  1 ^ 1 = 0
    
    1: 00000000000000000000000000000001
    1: 00000000000000000000000000000001
    -----------------------------------
    0: 00000000000000000000000000000000
    
    #2:  12 ^ 15 = 3
    
    12: 00000000000000000000000000001100
    15: 00000000000000000000000000001111
    ------------------------------------
     3: 00000000000000000000000000000011
    


    다시 말하지만, 이 코드( +isCreatedOnPresent ^ +isModifiedOnPresent )는 어떻게
    일하다? 두 변수 앞에 있는 +를 단항 더하기 연산자라고 합니다.
    값을 숫자로 강제합니다. 따라서 +isCreatedOnPresent는 다음과 정확히 유사합니다.Number(isCreatedOnPresent) . 그리고 이 두 변수는 boolean 유형이므로 ;
    그들은 1 또는 0 로 강제됩니다. 자바스크립트에서:

    Number(true); // 1
    Number(false); // 0
    


    이제 예를 들어 modifiedOnarg에 있지만modifiedOn가 아닙니다. 코드가 평가되는 방식은 다음과 같습니다.

    // isCreatedOnPresent = true, and isModifiedOnPresent = false
    const isOneTimestampMissing = +isCreatedOnPresent ^ +isModifiedOnPresent;
                             // = +true ^ +false;
                             // = 1 ^ 0;
                             // = 1;
    
    if (isOneTimestampMissing)
      // if (1)
      throw Error()
    
    // as 1 is a truthy value the error will be thrown
    


    결론



    솔직히 내 코드에서 XOR(^) 연산자를 사용하는 것은 좋은 생각이 아니라고 생각합니다.
    한 줄만 줄여도. 간결함을 위해 희생하기 때문에
    가독성이 높아 XOR에 대해 모르는 사람을 혼란스럽게 할 수 있습니다.
    운영자. 하지만 실제 사용 사례를 찾았고 공유하고 싶었습니다.
    너희들과 함께 😀.

    학점



    표지 이미지(Minecraft의 XOR Gate)는 Imgur에서 가져온 것입니다.

    좋은 웹페이지 즐겨찾기