틸드 연산자는 이진수에 대해 비트 단위로 적용되는 연산자로, 이진수의 0과 1을 반대로 바꾸는 연산자라고 한다.
console.log(~1) // -2
console.log(~2) // -3
console.log(~-1) // 0
console.log(~-2) // 1
양수 n에 ~
연산자를 사용할 시 -(n-1)
, 음수 n에 사용 시, (n+1)
로 변환되는 것을 확인할 수 있다.
이러한 성질을 이용하여 indexOf()
와 같이 -1을 반환하는 메서드에 ~
연산자를 사용할 수 있다.
const hello = 'hi';
if (hello.indexOf('hi') !== -1) {
console.log("포함!");
}
// ~ 연산자를 사용해 코드를 줄일 수 있다.
if (~hello.indexOf('hi')) {
console.log("포함!");
}
-1
에 ~
연산자를 사용할 경우 0을 반환하며, 자바스크립트에서는 0을 falsy하다고 보는 성질을 이용하여, 위처럼 코드의 양을 단축시킬 수 있다.
~
연산자와 기능은 동일하다.
특정 수 n에 ~~
연산자를 사용할 경우, ~
로 인해, n의 이진수의 0과 1의 위치를 바뀌고,
~
를 한번 더 사용하여 다시 0과 1의 위치를 바꾸기 때문에 동일하게 n이 반환된다.
double tilde연산자가 어떻게 유용하게 사용되는지 알아보자.
숫자에 ~
연산을 하게되면서 소수점들은 버려지게된다. 즉, ~~
를 활용하면 Math.floor()
처럼 활용할 수 있다.
console.log(~~(10/3)); // 3
console.log(~~(10/3) === Math.floor(10/3)); // true
Math.floor()
대신에 활용하는데 장점과 단점이 있다.
~~
가 빠르다. Math.floor
, ~~
, parseInt
의 속도를 비교했을 때 ~~
, Math.floor
, parseInt
순으로 ~~
가 가장 빠른 퍼포먼스를 보여줬다.위의 경우가 언제쓰일까 싶지만 undefined+3 => NaN
이런 상황이 자주 있었을 것이다.
예시 하나만 작성해 보자.
배열[1,1,1,2,2,3,3,3,3]을 각 숫자가 몇개인지 객체에 저장해보자.
const arr = [1,1,1,2,2,3,3,3,3];
const obj1 = {};
arr.forEach(v => {
if(obj1[v]) {
obj1[v] += 1
} else {
obj1[v] = 1;
}
})
//obj1 {1: 3, 2: 2, 3: 4}
위와같이 obj에 key값이 있는지 확인해주는 작업이 필요하다. 그렇지 않으면 NaN이 나올 것이다.
그럼 ~~
를 활용해 다시 코드를 작성해보자.
const obj2 = {};
arr.forEach(v => obj2[v] = ~~obj2[v] + 1);
//obj2 {1: 3, 2: 2, 3: 4}
undefined
가 나올 수 있는 상황을 ~~
연산자를 이용해서 간단하게 해결할 수 있다. 알고리즘 답안을 보면서 배운 연산자인 만큼 알고리즘에서 유용하게 사용할 수 있을 것 같다.