기본 콘텐츠로 건너뛰기

2월, 2023의 게시물 표시

-0과 +0을 구분 할 수 있을

 0에는 부호가 없다. 수학을 배우면서 0이라는 숫자에 부호를 작성해본 적이 없을 것이다. 게다가 0에 부호가 있는가 없는 가에 수학에서는 어떠한 것도 변하지 않는다.  그도 그럴 것이 0에 어떤 값을 더하던 원래 값 그대로 반환 될 것이고, 어떤 값을 곱하던지 0 일테니까 말이다.  실제로는 없겠지만, 자바스크립트에는 0에는 부호가 존재한다.  console.log로 작석된 대로 0, -0이 확실히 찍혀 있는 것을 알 수 있다. 하지만 !== 연산자로도, 양수가 더 큰 가에 대한 질의에도 그냥 같은 값이다. 결론이 날 수 밖에 없다. 뭐 물론 아래처럼 판단하는 것은 가능하다.  Object.is는 값을 비교하는 방법 중 하나라고 알아두면 된다. 나중에 자세하게 다룰 일이 있을지는 모르겠다.  위의 상황이 무엇이 문제가 될까? 일단 수학이라면 모르지만, 우리는 프로그래밍 하는 입장에서 숫자를 0으로 나눌 수 있지만, 그러한 상황은 피하려고 한다. 하지만 그렇게 되면 어떻게 될까 저 음수와 양수의 차이가 수학과 프로그래밍과 차이가 나는 부분이라고 말할 수 있겠다. let pos = 0 let neg = - 0 pos = 1 / pos // Infinity neg = 1 / neg // -Infinity console . log ( pos > neg ) // true 수학에서는 숫자를 0으로 나누는 것이 불가능 한 연산이지만, 자바스크립트에서는 가능하며, 결과 값이 0이 음수냐 양수냐에 따라서 무한과 음수부호의 무한으로 표현이 된다.  컴퓨터가 부호를 표현하는 방법  일단 컴퓨터는 0과 1로만 값을 인지 할 수 있고, -라는 기호는 사용하지 않는다. 하지만, 일반적으로 숫자 표현시 최상위 비트(0번째 인덱스)를 부호를 표현하는 값으로 사용 한다. 0이면 양수 1이면 음수.  일단 위의 근거 만으로도 자바스크립트에 0의 부호가 있는지가 풀린다.  일단, 4비트로 표현을 하려고 한다.  0010(2)는 다들 알다시피 양수 2라는 것을 알 수 있을 것이다.  10

가비지 컬렉션 핥기. (표시하고 쓸기)

 지난번에 가비지 컬렉션 알고리즘 중 하나인, 참조 세기를 확인 하였다. 이번에는 표시하고 쓸기 알고리즘을 확인 하려고 한다. 참조 세기의 단점인 서로 참조 하고 있는 상황에는 메모리에서 제거되지 않아, 문제가 있다고 말하였다.  표시하고 쓸기에서는 서로 참조 하고 있더라도 확실히 메모리에서 제거 할 수 있게 된다.  표시하고 쓸기를 간단하게 말하면, "닿을 수 없는 것을 메모리에서 제거한다."라고 설명 할 수 있다.  표시하고 쓸기(Mark-and-sweep) 가비지 컬렉션  닿을 수 없다. 라는 것을 확인 하기 위하여, roots라는 오브젝트 집합을 이용한다.  간단한 예시를 확인 해보자. 일단 우리는 roots라는 오브젝트를 확인 할 수 없으니, window가 roots중에 하나라고 생각 하자. var x = { a : [ 1 , 2 , 3 , 4 ] , b : 1 } var y = x . a  위의 상황에서 메모리를 표로 만들어 보자.  간단하게 위처럼 그릴수 있을 것이다. 이 상황에서 x의 값을 바꾸면 어떻게 될까? x = null  위처럼 더 이상 b(1)에 접근이 불가능 하게 된다. 이게 간단하게 표시한 표시하고 쓸기라고 보면 된다. 뭐 물론 위에서는 변수만 표현 하였지만. 실제로는 x의 값이 null로 바뀌었으니, {a, b} <= 이 객체 자체도 접근이 불가능하게 되니 메모리에서 해당 주소가 제거 될 것이다.  참조세기와 달리 닿지 않는 것을 메모리에서 제거를 하니 서로참조가 생기더라도 문제가 없다. 아래의 상황을 확인해보자. var z = { a : [ 1 , 2 ] } z . b = z . a z . a = z . b z = null  위처럼 root에서 접근 할 수 있는가? 에 대한 판단이기 때문에 위처럼 서로 참고 하고 있다하더라도 위처럼 제거 하게 된다.  조금 더 자세하게 설명 하기 위해 간단한 코드로 해당 로직을 살펴보자. // for each root in the roots {

가비지 컬렉션 핥기. (참조 세기)

  가비지 컬렉션이라고 많이 들어보았을 것이다. 옛날부터 개발한 사람이라면, java를 하면서 배웠을 테고, 요즘에 프런트엔드 학원에서 알려줄 지는 모르겠지만, javascript 또한 가비지 콜렉션이 있다.  가비지 컬렉션은 무엇일까? 간단히 말하자면, 사용하지 않는 메모리를 반환해주는 시스템이다. 고전적으로 c언어에서는 메모리를 할당 하는 행위를 malloc(), 해제하는 행위를 free() 두가지 함수를 사용 하여, 개발자가 직접 메모리 관리는 하였다. 뭐 물론 개발자가 전지전능하지는 않기에, 사용해야 함에도 메모리 해제를 하거나, 도달하지 못하는 변수에 메모리 할당 되어있는 경우도 있어서 메모리 누수가 발생 하기도 하였다.  가비지 컬렌션에서 가장 중요한 것은 무엇일까? 사용하지 않는 메모리 이것을 어떻게 아는가 이다. 당연하게도, 개발하는 도중에는 알 수 있는 정보이다. 하지만, 당신의 컴퓨터가 해당 변수가 언제부터 사용이 되지 않는지 알 방법은 없다. 뭐 물론 프로세스가 종료 되면 모든 메모리가 해제 될 것이다.  참조 세기(reference-counting) 가비지 컬렉션  * 요즘 브라우저는 더 이상 사용 하지 않지만, 왜 사용하지 않는지는 알아 주었으면 한다.  간단한 발상이다. 해당 변수를 참조하고 있는 변수가 있는지 확인을 하는 것 뿐이다. 예를 들어보자. var x = { a : [ 1 , 2 , 3 , 4 ] , b : 1 } var y = x . a  위의 상황에서 메모리를 표로 만들어 보자.  간단하게 위처럼 그릴수 있을 것이다. 이 상황에서 x.a의 값을 바꾸면 어떻게 될까? x . a = 'test'  [1, 2, 3, 4]의 값의 참조 횟수가 줄어들 것이다. 다시 한번 y이 값을 바꾸자. y = x . a  y에서 접근 가능 했던, [1, 2, 3, 4]는 더 이상 참조 되지 않고, 가비지 컬렉션에 의하여 메모리에서 제거 되게 된다.  일단 refrence-counting 방식은 이와 같다. 그렇다면

arguments 파해치기.

 사실 arguments는 그리 자주 쓰는 객체는 아니다. 하지만 화살표 함수( arraow function )를 배우는 사람이라면 화살표 함수( () => {} ) arguments가 없다는 설명을 들은 적은 있을 것이다.  오늘은 arguments가 어떤 속성을 가지고 있는지, 또 어떤 상황에서 사용 할 수 있을지 확인 해보도록 하자. 예제 코드를 위주로 다룰 터이니 한 번 살펴보고 적절한 상황에서 사용해보자.  arguments? function foo (a , b) { console . log (a , b) // 1 2 console . log (arguments) // Arguments(2) [1, 2, callee: ƒ, Symbol(Symbol.iterator): ƒ] } foo ( 1 , 2 )  일반 함수(function)에서 사용 할 수 있는 객체로 함수 호출시의 인자들을 확인 할 수 있다.  => a, b는 매개변수(parameter) foo( 1, 2 ) 인자(argument)라고 보면 된다.  함수 호출 시의 값을 알 수 있기에,  function foo (a , b) { console . log (a , b) // 1 2 console . log (arguments) // Arguments(2) [1, 2, 3, callee: ƒ, Symbol(Symbol.iterator): ƒ] } foo ( 1 , 2 , 3 )  위와 같이 정의 되지 않은 매개변수도 받을 수 있다.  arguments.length  arguments는 길이를 가지고 있다. 인자의 갯수를 알려준다. 하지만 배열은 아니다. 정확히는 키와 값을 가지고 있는 Map에 더 가까운 구조를 가지고 있다. 아래의 JSON.stringify만 보더라도 확인이 가능하다. function foo (a , b) { console . log (arguments. length ) // 3 console . log (arguments[