https://ko.javascript.info/javascript-specials
수학연산을 제공하는 내장'객체' 이므로 typeof 찍으면 object출력
typeof null의 결과는 object이다. Null은 별도의 고유한 자료형을 가지는
특수 값으로 '객체가 아니지만' 하위호환성을 유지하기 위해 이런 오류를 수정하지 않고
객체 type으로 남겨놓은 상황이다.
메시지가 있는 작은 창을 모달창이라고 부른다
let age = prompt('Write Your age', 100);
alert(`your age is ${age}.`);
사용자가 확인 또는 취소버튼을 누를 때 까지 메시지가 창에 보여지는 메서드이다.
String() 하면 스트링으로 바꿔줌.
Number() 하면 숫자형으로 바꿔줌.
JS 는 사전순으로 문자를 비교한다. 사전편집(lexicographical)순이라고 불리기도 하며 이 기준 적용시 사전 뒤쪽의 문자열은 앞쪽의 문자열보다 크다고 판단된다
예를 들어 아래와 같은 결과가 나온다.
alert('z'>'a')// true
또 추가적인 순서가 존재하는데 아래와 같다.
alert('Bee'>'Be') //true
그런데 재밌는 점은 대문자인 A보다 a 가 더 크다고 판단된다는 점인데 이는 인코딩표인 유니코드에서는 소문자가 대문자보다 더 큰 인덱스를 가지기 때문이다.
null === undefined // false
null == undefinded //true
첫번째 false케이스는 두값의 자료형이 다르기 때문에 false가 반환되는것이다
두번째 true케이스는 특별한 규칙의 적용으로 true가 반환되는데 null과 undefined를 각별한 커플처럼 취급한다.
신기한건 null은 숫자로 변환하면 0 undefined는 NaN으로 반환된다.
따라서 null >= 0
은 true
이다.
undefined는 뭘 비교하던 False가 뜰테니 그냥 불친절한 친구로 알고 있자.
0은 false 1은 true로 판단되며
0, 빈문자열 , "", null, undefined,NaN은 boolean형으로서 변환시 모두 false가 된
let result = condition ? value1 : value2;
let accessAllowed = (age > 18) ? true; false;
let age = prompt ('나이를 입력해주세요 !.', 18);
let message = (age<3)? '아기야 안녕?' :
(age<18) ? '안녕?' :
(age < 100) ? '환영합니다!' :
'나이가 아주 많으시거나 , 나이가 아닌 값을 입력하셨군요!';
alert(message);
if( age < 3 ){
message = "아기야 안녕?'
}
else if (age<18){
message = "안녕?"
}
else if (age<100){
message = '환영합니다!'
}
deleteComment = (id)=>{
this.setState({comments: this.state.comments.filter(comment => comment.id !== id) });
}
null 병합연산자(nullish coalescing operator)??
를 사용하면 여러 피연산자 중 그 값이 확정되어있는 찾을 수 있다!!
상황에 따른 a??b
의 결과를 보자!
하나의 예를 더 살펴보면 이해가 쉽다!
let firstName = null; let lastName = null; let nickName = "violet"; console.log(firstName ?? lastName ?? nickName ?? "Hello,World!")
위 예시의 답은 무엇일까하면 'violet'이 출력된다 만약 위 상태에서 아래와 같이 연산순서를 변경해주면 출력값이 달라진다.
console.log(firstName ?? lastName ?? "Hello,World!" ?? nickName)
이렇게 하면 "Hello, World!"가 출력되는데 이유는 ?? (null 병합연산자) 는 null 이나 undefined가 아닌 '첫번째' 인자를 출력해주기 때문이다
null 병합연산자와 or의 차이는 크게 없어 보이지만 중요한 차이점이 있다고 한다.
- ||는 첫번째 truthy값을 반환한다.
- ??는 값이 정의되어 있는 '첫번째'값을 반환한다.
아래와 같은 예시를 보면 할당되는 차이가 보일 것인데 ?? 같은 경우는 미리 0이 할당이 되어 있기때문에 undefined나 null에 해당 되지 않으므로 0을 반환하는 반면 ||의 경우 height에 할당된 0 을 flasy한 값으로 취급하여 null이나 undefined와 동일하다고 처리해버렸다.
let height = 0;
console.log(height || 100); // 100
console.log(height ?? 100); // 0
정리하자면 ?? 연산자는 undefined나 Null이 '할당'되어 있을 때만 그 친구들을 제외하고 나머지 비교 대상중 정의된 첫번째 순서의 값을 반환하는 것이다.
먼저 조건을 걸어준 5미만 보다 작은 3이 될때 나오고 싶을 경우 아래처럼 'break'를 이용해서 빠져 나올 수 있다는 것을 보자 출력값은 3 이된다
만약 이것을 활용한다면 반복문의 시작 또는 끝의 인덱스에서 숫자를 확인하는 것보다 객체 또는 배열의 여러곳에서 조건에 알맞는 것들을 확인하며 사용할 경우에 유용할 것 같다.
위의 사진 처럼 while문에서 참의 값을 조건으로 넣어놓으면 무한반복이 될텐데 break로 해당조건을 이용하면 간단하게 해당인덱스를 찾아낼 수 있다( 물론 반복되는 숫자들을 찾아 넣으려면 더 복잡해질 수도 있겠다)
continue는 break의 약한(weak)버전이라 생각하면 쉽다고 하는데 break는 해당 조건을 만나면 반복문을 멈춰버린다면 continue는 해당 조건을 만족하는 것을 제외한 나머지들을 반환해버린다
아래와 같은 예를 보면 이해가 쉽다
if 문 내의 짝수가 되는 조건인 요소는 '제외 당하고' 나머지 요소들만 반환되며 이것을 push메서드를 통해 배열로 넣어주면 쉽게 범위내의 홀수들을 가진 배열을 만들 수 있다!
continue다음 특정 label을 붙여놓는다면 조건에 적합한것을 제외한 뒤 다시 라벨의 위치로 돌아가게 된다
let n = 10;
label:
for (let i = 2; i <= n; i++) { // 각 i에 대하여 반복문을 돌림
for (let j = 2; j < i; j++) { // 제수(나눗수)를 찾음
if (i % j == 0) continue label; // 소수가 아니므로 다음 i로 넘어감
}
console.log( i ); // 소수
}
https://ko.javascript.info/switch
askit code
stack
stack자료구조에 pop, push 메서드 써보기
키를 가진 데이터 여러개를 하나의 엔티티에 저장할때는 객체를 , 컬렉션에 데이터를 순서대로 저장할때는 배열을 사용한다.
객체나 배열을 전달하는 경우가 생길 때 저장된 데이터 전체가 아닌! 일부만 필요한 경우가 생기기도하는데 이럴 때 객체나 배열을 변수로 분해할 수 있게 해주는 특별한 문법구조를 구조분해할당(Destructurinf assignment)이라고 한다.
ex) 함수의 매개변수가 많거나 매개변수 기본값이 필요한 경우 등에서 destructuring은 그 진가를 발휘한다.
아래 간단한 예제를 보자!
https://ko.javascript.info/ifelse
아래와 같이 ... 을 통해 나머지를 긁어 올 수 있고 그것들은 나머지배열요소들이 저장된 새로운 배열이 된다.
let [name1,name2, ...rest] = ["Julis", "Caesar", "A","B","C"]
console.log(name1) // Julis
console.log(name2) // Caesar
console.log(rest[0])// A
console.log(rest[1]) //B
할당하고자 하는 변수의 개수가 분해하고자 하는 배열의 길이보다 크더라도 에러가 발생하지 않습니다. 할당할 값이 없으면 undefined로 취급되기 때문입니다.
객체분해하기 부터 시작하면된당.
객체안에서 의 다른객체에도 접근하는 방법이 존재한다!
const topK = (nums, k) => {
let count = 0
let sampleObj = {}
let sampleArr = []
for(let i = 0; i<nums.length ; i++){
for (j in nums){
if( nums[i] == nums[j]){
count += 1
}
sampleObj[nums[i]] = count
}
count = 0
}
console.log(sampleObj)
let keySorted = Object.keys(sampleObj).sort((a,b)=>sampleObj[b]-sampleObj[a])
console.log(keySorted)
for(let l = 0; l < k; l++){
sampleArr[l] = Number(keySorted[l])
}
return sampleArr
}
topK([1,1,2,2,2,2,3,3,3,3], 2)
함수선언에는 크게 세가지 방식 존재
함수선언을 하는 간단한 방법
질리도록 봤으니 간단한 코드만 보고 넘어가겠다.
function name(parameters){
code...
} //declaration, definition
name(); // call
let name = function(parameters){
code...
} //declaration, definition
name(); // call
let name = (parameters)=>{
conde...
}
함수는 대개 어떤 동작을 하기위해 코드를 모아놓는 것이기 때문에 이름을 지을 때 동사로 명칭하는것이 좋다.
어떤 동작을 하는지 축약해서 설명해주는 동사를 접두어로 붙여 함수이름을 만드는 것이 관습인데 보통 팀내에서 합의된 접두어를 붙여 사용해야한다.
예를 들어 show
로 시작하는 함수는 대개 무언가를 보여주는 함수이다.
이 외에도 아래와 같은 접두어를 사용할 수 있다고한다( 모던자바스크립트 짱짱)
- "get…" – 값을 반환함
- "calc…" – 무언가를 계산함
- "create…" – 무언가를 생성함
- "check…" – 무언가를 확인하고 불린값을 반환함
그리고 함수는 하나의 동장만 담당하는 것이 좋다. 개발자들이 빈번히 하는 실수가 독립적인 두개의 동작을 하나의 함수에 합쳐버리는 것이라고 한다.
TIPS
아래 두가지는 동일한 결론이 나오게 된다.
함수 표현식은 변수에 함수를 할당하는 방식이라고 보면 쉽다!
function sayHi(){
console.log("wassup")
}
let sayHi = function(){
console.log("wassup")
};
Tip
변수에 함수를 할당한케이스의 마지막에는 ;
가 있는 것을 볼 수 있다. 보통 중괄호로 만든 코드 블록 끝에는 없어도 된다. 위의 경우 let sayHi = code...;
로 여겨지기 때문에 이런식으로 표현이 된것이다.
표현식과 선언문의 차이는 독자적인가 syntax construct내부에 생성되는가의 차이이다.
자바스크립트에서는 함수표현식이 실제 실행흐름이 해당함수에 도달 했을 때 함수를 생성한다고 한다. 따라서 실행흐름이 함수에 도달하지 못하면 사용할 수가 없는 것이다. 그러나 함수선언문은 선언문이 정의되기 전에도 호출을 할 수 있다(호이스팅) 자바스크립트는 스크립트를 실행하기전 준비단계에서 전역에 선언된 함수 선언문을 찾고 해당함수를 생성한 뒤 실행되기 때문이다.
함수를 함수의 인수로 전달하고, 필요하다면 인수로 전달한 그 함수를 "나중에 호출(called back)"하는 것이 콜백 함수의 개념입니다.