데이터 구조의 동등성: Ruby 대 JavaScript

최근 몇 주 동안 나는 동료와 함께 Reginald Braithwaite(함수형 프로그래밍 렌즈를 통해 JS의 기초에 대한 탁월한 시각)의 JavaScript Allongé을 읽었습니다. 내 동료가 그녀에게 이해가 되지 않는 것을 꺼냈습니다.

In JavaScript, why isn't an empty array equal to an empty array? What's the difference between the two identical objects?





잠시 동안 JavaScript로 작업한 사람에게는 대답이 간단해 보일 수 있습니다. "그들은 두 개의 다른 배열입니다. 물론 하나는 다른 것과 같지 않습니다!"그러나 내 친구와 같은 Rubyist는 다르게 볼 수 있습니다. 내가 보기에 이것은 Ruby와 JavaScript에서 비교 연산자의 의미 사이의 철학적 차이입니다. 한 언어는 개체 동등성 개념을 사용하여 데이터 구조를 비교하는 반면 다른 언어는 명시적으로 개체 ID를 확인합니다.

참고: JS double equal 또는 Ruby's threequal 연산자는 단순한 비교 연산자 이상이므로 논의하지 않겠습니다.



Ruby의 데이터 구조 동등성



Ruby에서 ==의 내장 동작을 사용하여 데이터 구조를 비교할 때 실제로 객체의 내용을 비교하는 것입니다. 배열의 경우 요소의 순서가 다음과 같은지도 확인합니다. 둘 다 동일합니다. 이는 메모리에서 서로 다른 개체를 가리키는 두 변수가 같을 수 있음을 의미합니다.

> first_array, second_array = [1,2,3], [1,2,3]

> first_array == second_array
=> true


어떤 이유로 두 변수가 동일한 개체를 참조하는지 확인하고 확인하려는 경우 개체의 ID를 확인하거나 .equal? 메서드를 사용하는 것이 좋습니다.

> first_array, second_array = [1,2,3], [1,2,3]

> first_array.object_id == second_array.object_id # 70176467875700 == 70176467875680
=> false
> first_array.equal?(second_array) # a clearer way to perform this comparison
=> false


JavaScript와 달리 Ruby의 비교 연산자는 실제로 비교하려는 클래스에 정의된 메서드입니다(이 개념에 대한 멋진 연습here). ==는 메서드일 뿐이므로 원하는 경우 재정의할 수도 있습니다! 서로 비교해야 하는 사용자 지정 클래스를 작성하는 경우 이는 합리적인 방법입니다. 아래의 어리석은 예 :

> class Ditto
*   def self.==(other)
*     true
*   end
* end

> Ditto == 'Pikachu'
=> true
> Ditto == 2
=> true
> Ditto == false
=> true




JavaScript에서 데이터 구조의 동등성



Ruby와 달리 JavaScript는 필요하지 않기 때문에 개체에 대한 고유 ID를 노출하지 않습니다. 데이터 구조는 기본적으로 ID로 비교됩니다. 두 변수가 같으면 메모리에서 동일한 개체를 가리키는지 확인할 수 있습니다.

> const firstArray = [1,2,3]
> const secondArray = [1,2,3]
> firstArray === secondArray
false


두 개의 개별 데이터 구조가 동일한 콘텐츠를 가지고 있는지 확인하고 확인하려면 확인할 논리를 직접 작성하거나 Lodash 과 같은 라이브러리의 함수를 사용해야 합니다.

// Super naïve implementation:
const arraysAreEqual = (array1, array2) => {
  return array1.every((el, index) => el === array2[index])
}
> arraysAreEqual([1,2,3],[1,2,3])
true
> arraysAreEqual([1,2,3],['a','b','c'])
false


TL; DR



JavaScript===는 비교하는 두 변수가 동일한 데이터 구조를 가리키는지 확인하고 Ruby== 메서드는 두 배열 또는 해시의 내용이 동일한지 확인합니다.



Ruby's [1,2,3] == [1,2,3]는 JS에서 [1,2,3].every((el, index) => el === [1,2,3][index])로 번역됩니다.

JavaScript의 [1,2,3] === [1,2,3]는 Ruby에서 [1,2,3].equal?([1,2,3])로 변환됩니다.

참조



바라건대 이것이 데이터 구조를 비교할 때 두 가지 다른 언어가 기대하는 바를 이해하는 데 도움이 되기를 바랍니다! 더 깊이 파고들고 싶다면 몇 가지 참고 자료를 정리했습니다.
  • MDN docs on equality and sameness in JS

  • A fun JavaScript equality table (if() 설명에 대한 보너스 포인트!)
  • Intro to Ruby's Comparison Operators
  • RubyMonk's custom .== method example
  • 좋은 웹페이지 즐겨찾기