라벨이 javascript인 게시물 표시

[JavaScript] null 병합 연산자 (??) - (nullish coalescing operator)

null 병합 연산자 (??) 를 사용하면 여러 피연산자 중 확정 되어있는 변수를 찾을 수 있다. 확정되어있는 변수라는 말은 정의된 값을 말한다. 즉, null과 undefined 값이 아닌 모든 값을 true로 인식한다는것이다. null 병합 연산자를 사용하는 이유 const age = 45 ; const userAge = age || "secret" ; console . log ( userAge ); // 45 const num = null ; const count = num || "undefined" ; console . log ( count ); // undefined 위 예제와 같이 or 연산자를 사용하여 코드를 많이 작성한다. 앞에 값이 false이면 뒤에 값을 반환하고, 앞에 값이 true이면 뒤에 값을 반환한다. 하지만 여기서 문제점이 발생한다. 일반적으로 false로 인식되는값들은 아래와 같다. false, '', 0, null, undefined 이러한 false로 인식되는 값들이 상황에 따라 문제를 발생시킨다. 상황에따라 사용자에게 값을 받을때 0을 받거나 ' ' 공백을 받을 수 있다. 그런데 이러한 경우에도 false로 인식되어 원하는 방식대로 코드가 동작하지 못하게된다. 아래에 예시로 문제점을 확인해보자. // ex1) 애기의 나이를 사용자로부터 받아올 떼 const babyAge = "" ; const userAge = babyAge || "secret" ; console . log ( userAge ); // secret // ex2) 물 섭취 횟수를 사용자로부터 받아올 떄 const drinkCount = 0 ; const totalCount = drinkCount || "undefined" ; console . log ( count ); // undefined or 연산자를 사용

[JavaScript] 옵셔널 체이닝 (optional chaining)

이미지
옵셔널 체이닝( ?. )을 사용하면 프로퍼티에 작성되지않은 중첩객체로 발생되는 에러를 해결할 수 있다. const information1 = { team : "A" , detailOption : { name : "lee" , age : 30 , score : { first : 10 , second : 30 , third : 50 , }, }, }; const information2 = { team : "C" , detailOption : { name : "kim" , age : 30 , }, }; const getInformation = ( person ) => { console . log ( person . detailOption . score . third ); }; getInformation 함수에 information1 을 전달하면 숫자 50을 반환하지만 getInformation 함수에 information2 을 전달하면 아래와 같이 오류를 반환한다. 에러 발생 원인은  information2 내부에 프로퍼티에 작성된 중첩객체 detailOption 내부의 프로퍼티에 작성된 score에 프로퍼티로 third가 작성되지 않았기 때문이다. 이렇게 오류가 발생할때 && (AND)연산자를 사용하여 아래와 같이 해결할 수 있었다. const information1 = { team : "A" , detailOption : { name : "lee" , age : 30 , score : { first : 10 , second : 30 , third : 50 , }, }, }; const information2 = { team : "C&qu

[JavaScript] 프로미스 API (Promise.all/Promise.race)

Promise.all 여러개의 프로미스를 동시에 실행시키고 모든 프로미스가 완료된 후 데이터를 처리할 때 사용한다. 사용법 let promise = Promise . all ([... promises ...]); Promise . all ([ new Promise (( resolve ) => setTimeout (() => resolve ( 1 ), 3000 )), new Promise (( resolve ) => setTimeout (() => resolve ( 2 ), 2000 )), new Promise (( resolve ) => setTimeout (() => resolve ( 3 ), 1000 )), ]). then ( console . log ); // 프라미스 전체가 처리되면 [1, 2, 3]이 반환된다. 각각의 프라미스는 배열 구성 요소가 된다. 배열안에 작성한 프로미스가 모두 처리된 후 새로운 프로미스가 이행되며 배열안에 작성한 프로미스의 결과 값들을 담은 배열이 새로운 프로미스로 반환된다. Promise.all은 특이한점이 있는데 위 예시에서 볼 수 있듯이 Promise.all의 배열안에 작성한 프로미스들은 처리되는 순서와는 상관없이 작성한 순서대로 값을 반환한다.  Promise.all은 아래와 같이도 사용될 수 있다. let urls = [ "https://api.test1.com/users/lee" , "https://api.test2.com/users/kim" , "https://api.test3.com/users/park" , ]; // fetch를 사용하여 url을 프라미스로 매핑한다. let requests = urls . map (( url ) => fetch ( url )); console . log ( requests ); // [Promise, Promise, Promise] //

[Javascript] currentTarget VS target 차이점

이미지
자바스크립트를 공부하다가 어떤 블로그는 target을 사용해서 이벤트를 처리하고 다른 블로그는 currentTarget을 사용해서 이벤트를 처리하고있었다. 찾아보니 이벤트 버블링으로 인해 둘을 구분해서 사용한다고 한다. 예제를 통해 둘을 비교해보면 import React , { useEffect } from "react" ; function LangingPage () { const clickTest = ( e ) => { console . log ( e . target ); console . log ( e . currentTarget ); }; return ( < div > < h1 > 시작 페이지 </ h1 > < li > < button onClick = { clickTest } > < span > 제출 </ span > </ button > </ li > </ div > ); } export default LangingPage ; 위 예제는 리액트로 작성했다. 버튼을 클릭해보면 아래와 같이 다르게 결과물이 출력되는것을 확인할 수 있다. 출력 순서는 target, currentTarget 순이다. target은 실제로 내가 클릭한 태그를 반환하고 currentTarget은  onClick 이벤트가 작성되어있는  태그를 반환한다. 여기서 이벤트 버블링이라는 개념이 적용되는데 span 태그를 클릭했어도 이벤트 버블링으로 인해 이벤트가 button 태그까지 전달되어 button 태그에 작성된 onClick 이벤트가 동작하게된다. 이벤트 버블링으로인해 onClick 이벤트에서는 어느 태그가 클릭되었는지 target event로 알 수 있다. 자세한 설명이 적혀있는 참고 링크를 아래에 첨부해 두었다

[JavaScript] arrow function(화살표 함수)를 사용해서는 안되는 경우

1. 객체안에 메서드 2. prototype 3. 생성자 함수 4. addEventListener 함수의 콜백 함수 1,2,3,4번 에서 사용하는경우 this는 window를 가리키게되므로 원하는데로 동작하지 않는다.

[JavaScript] 심볼(Symbol)

심볼(Symbol)은 유일한 식별자(unique identifier)를 만들고 싶을 때 사용하거나 동시 다발적으로 일어날 수 있는 코드에서 우선순위를 주고 싶을때 정말 고유한 식별자가 필요할 때 쓰여진다. Symbol( ) 또는 Symbol.for() 을 사용하면 심볼값을 만들 수 있다. Symbol을 사용하여 주어지는 String에 상관없이 동일한 String을 사용하더라도 고유한 식별자를 만들 수 있다. const symbol1 = Symbol ( 'id' ); const symbol2 = Symbol ( 'id' ); console . log ( symbol1 === symbol2 ); // false 만약 String이 똑같다면 동일한 Symbol 을 만들고 싶다면 Symbol.for()을 사용해서 아래와 같이 동일한 Symbol을 만들 수 있다. const symbol1 = Symbol . for ( 'id' ); const symbol2 = Symbol . for ( 'id' ); console . log ( symbol1 === symbol2 ); // true Symbol을 출력할 때에는 변수를 바로 사용하면 에러가 발생하므로 아래와 같이 심볼명.description 을 사용하여 String으로 변환하여 출력해야 한다. const symbol1 = Symbol . for ( 'id' ); const symbol2 = Symbol . for ( 'id' ); console . log ( symbol1 === symbol2 ); // true console . log ( symbol1 . description ); // id

[JavaScript] 계산된 속성명 또는 계산된 프로퍼티 이름(Computed property names)

계산된 프로퍼티 이름은 객체의 key값을 동적으로 생성할때 사용된다. 객체 리터럴의 프로퍼티 자리의 key 값에 대괄호 [ ] 를 사용한다.  대괄호 [ ] 에 들어올 수 있는 값은 무조건 문자열이여야 한다. let prop = 'blogger' ; let obj = { [ prop ]: 123 }; console . log ( obj ); // { blogger: 123 } 위 예시에서는 변수 prop의 값이 obj 객체의 키값으로 할당되었다. 아래와 같이 사용자에게 동적으로 key값을 받아와 프로퍼티의 key값으로 사용할 수 있다. let fruit = prompt ( "어떤 과일을 선택했습니까?" ); let list = { [ fruit ]: 5 }; console . log ( bag . apple ); // fruit에 "apple"이 할당되었다면, 5가 출력됩니다. 아래와같이 여러방법으로 사용된다. let i = 0 ; let obj = { [ '사람' + ++ i ]: i + '번' , [ '사람' + ++ i ]: i + '번' , [ '사람' + ++ i ]: i + '번' , } console . log ( obj ); // { '사람1': '1번', '사람2': '2번', '사람3': '3번' } const items = [ "A" , "B" , "C" ]; const obj = { [ items ]: "Hello" } console . log ( obj ); // A,B,C: "Hello" console . log ( obj [ "

[JavaScript] 자바스크립트 엔진의 종류

 자바스크립트 엔진의 종류 V8 : 오픈소스로 구글에서 개발했다. C++로 작성되었으며, 구글 크롬과 Node.js에서 사용된다. 가장 유명하다. SpiderMonkey : 최초의 자바스크립트 엔진이다. 넷스케이프 네비게이터 웹 브라우저를 위해 브랜던 아이크에 의해 개발되었다. 지금은 모질라 파이어폭스에 사용된다. Rhino : 모질라 재단에서 운영한다. 오픈소스이며, 전체가 자바로 개발되었다. JavaScriptCore : 오픈소스, 니트로라는 이름으로도 알려져 있으며 애플이 사파리를 위해 개발했다. Chakra(Jscript9) : 인터넷 익스플로러용이다 Chakra(JavaScript) : 마이크로소프트 엣지용이다. Nashron : 오픈JDK의 일환으로 오픈소스이며 Oracle Java Languages and Tool Group이 개발하였다. JerryScript : 사물인터넷을 위한 경량 엔진이다.

[JavaScript] innerHTML, textContent, innerText 차이점 비교

innerHTML 많은 사람들이 사용하고있고 나 또한 온라인 강의로 Javascript를 배울 때 모든 강의에서 innerHTML을 사용하고 있었다.  그런데 위 세가지 방법중 가장 추천하지 않는 방법이다. 체감적으로 느낄 수 있을지 모르겠지만 다른 방법들에 비해 파싱이 느리고  잠재적인 보안 위험(XXS 공격)이 발생할 수 있다는 점이다. 보안 문제 참고 https://developer.mozilla.org/ko/docs/Web/API/Element/innerHTML#security_considerations textContent innerHTML 보다 성능과 보안에 강점이 있다.  innerHTML의 경우 이름 그대로 HTML을 반환한다. 상황에 따라 innerHTML을 사용해 요소의 텍스트를 가져오거나 쓰는 경우가 있지만, HTML로 분석할 필요가 없다는 점에서 textContent의 성능이 더 좋다. 또한 innerHTML에서 언급되었던 잠재적인 보안 위험인 XXS공격의 위험이 없다. innerText textContent는 <script>와 <style> 요소를 포함한 모든 요소의 콘텐츠를 가져온다. 반면에 innerText는 사람이 읽을 수 있는 요소만 처리한다. textContent는 노드의 모든 요소를 반환한다. 그에 비해 innerText는 스타일링을 고려하며, 숨겨진 요소의 텍스트는 반환하지 않는다. 또한, innerText의 CSS 고려로 인해 innerText 값을 읽으면 최신 계산값을 반영하기 위해 리플로우가 발생한다. (리플로우 계산은 비싸므로 가능하면 피해야한다.) Internet Explorer 기준, innerText를 수정하면 요소의 모든 자식 노드를 제거하고, 모든 자손 텍스트 노드를 영구히 파괴한다. 이로 인해, 해당 텍스트 노드를 이후에 다른 노드는 물론 같은 노드에 삽입하는 것도 불가능하다. 그러므로 textContent를 사용하도록 하자

[JavaScript] 일급 객체, 고차함수

일급 객체 자바스크립트에서 숫자, 문자, 함수는 모두 일급 객체이다.  이러한 일급 객체는 아래와 같은 특징을 가지고있다. 1. 함수의 매개변수로 전달 할 수 있다. 2. 함수의 반환 값이 될 수 있다. 3. 변수 또는 데이터 구조에 담을 수 있다. 함수가 값으로 다뤄질 수 있다. 1. 함수의 매개변수로 숫자, 문자 뿐만아니라 함수도 전달 할 수 있다. const parameterFunc = ( num , f ) => num + f () ; parameterFunc ( 20 , () => 2 ) ; // 22 2. 함수가 숫자와 문자를 반환(return)하듯 함수도 함수를 반환할 수 있다. const returnFunc = () => () => 10 ; returnFunc () // () => 10 3. 숫자를 변수에 할당하듯 함수도 변수에 할당할 수 있다. let one = 1 let two = () => 2 고차함수 고차함수는 인자로 함수를 받거나 함수를 반환(return)할 수 있는 함수를 말한다. const higher_order_function = ( parameter_function ) => { parameter_function () ; }; higher_order_function ( () => { console . log ( " 고차함수 입니다. " ) } ) ; // 고차함수 입니다. 출력 : 고차함수 입니다.

[JavaScript] try/catch/finally + throw (에러 핸들링)

이미지
일반적으로 에러가 발생하면 스크립트가 제대로 동작하지 못하게 된다. 이러한 에러를 사람이 완벽하게 예측하여 처리할 수 없기 때문에 try ~ catch 문법을 사용하면 예상치 못한 에러에대하여 대응을 할 수 있다. try ~ catch 문법은 try 와 catch 라는 필수적인 두개의 블록이 존재하며  상황에따라 추가하여 사용할 수 있는 finally 도 존재한다. try { // 수행할 코드 } catch ( error ) { // 에러 핸들링 } try 블럭 내부에 수행할 코드를 작성하고 해당코드가 정상적으로 실행되면 catch 블럭을 건너뛰고 다음 코드를 이어 실행한다. 반면에 try 블럭 내부에 수행할 코드에 에러가 발생하면 try 블럭 내부의 코드 실행이 중단되고 catch 블럭으로 에러에 대한 객체가 인자로 넘어가면서 catch 블럭안에서 에러를 처리할 수 있다. 매개변수 error로 전달되는 에러 객체에는 무슨 문제가 발생했는지에 대한 설명이 담겨있다. 인자로 전달된 error 객체에는 name, message, stack 프로퍼티가 존재한다. 각각의 프로퍼티를 알아보면 error.name : 에러 명칭 error.message : 에러에대한 상세 내용을 담고있는 메세지이다. error.stack : 에러가 발생한 순간의 스택 (디버깅시 사용) try ~ catch 문법은 런타임 환경에서 실행되며 런타임 환경에서 발생하는 Error를 런타임 에러(runtime error) 또는 예외(Exception)라고 부른다. 에러 던지기 throw try ~ catch를 사용하여 예외( Exception )를 잡아낼 수 있지만 에러 종류와 관계없이 동일한 방식으로 에러를 처리해 주기 때문에 디버깅을 어렵게 만든다. 그러므로 추가적인 자세한 정보를 담은 에러를 만들어야 한다, 사용방식은 아래와 같다. throw 'errrorrr' ; // 던지는 것에 타입 제한은 없으나 throw new Error ( 'throw erro

[JavaScript] setTimeout, setInterval, clearInterval 비교

JavaScript setTimeout, setInterval, clearInterval 비교 setTimeout 메서드는 일정시간 후 함수를 실행한다. (1초후 출력) setTimeout(fn, delay) setInterval 메서드는 일정시간마다 함수를 실행한다.  (1초마다 출력) setInterval(fn, delay) 한가지 주의할점은  fn에 함수가 오지않으면 setInterval도 반복하지 않고 setTimeout과 같이 한번만 실행한다. clearInterval 메서드는 setInterval로 반복중인 작업을 중단시킨다. clearInterval(setInterval로 생성된 변수) clearInterval을 사용하기 위해서는 위의 비동기 함수들을 변수에 할당하고 해당 변수를 clearInterval의 매개변수로 대입헤 줘야한다.

[JavaScript] 기본연산자 ( +, -, *, /, **, % )와 연산자 우선순위

JavaScript 연산자 JavaScript에서 많이 사용되는 기본적인 연산자들에 대해 알아보려고 한다. + 의경우 숫자+숫자 연산시 숫자 결과값을 반환한다.  반면에 숫자+문자열(숫자)인경우 두 숫자를 계산하지 못하고 결과값으로 문자열을 반환한다. ex) 5 + 5 = 10 5 + '5' = 55 숫자형이 아닌 피연산자에 +를 붙여주면 숫자형으로 변화한다. ex1) +true => 1 +'' => 0 +'가나다' => NaN  ex2) let stringNum1 = '2'; let stringNum2 = '3'; stringNum1+stringNum2 = '23'; (+stringNum1)+(+stringNum2) = 5;  또는 +stringNum1 + +stringNum2 = 5; 처럼 연산자와의 간격을 줘도 계산이 가능해진다. 이렇게 말고도 Number(...)를 사용해도 문자열타입의 숫자를 숫자로 형변환이 가능하다. Number(stringNum1)+Number(stringNum2) = 5; -, *, /, **, % -      마이너스 연산자 *      곱하기 연산자 /      나누기 연산자 **    거듭제곱 연산자 %    나머지 연산자 아래 예제는 + 연산자와 같이 몇가지 알아두면 좋을만한 위 연산자들의 특성 ex) 5 - 5 = 0 5 - '5' = 0 5 * 5 = 25 5 * '5' = 25 4 % 3 = 1 4 % '3' = 1 3 * '가' = NaN 3 * 'apple' = NaN 3+'3'+3+'3' - 1 = 3332 연산자 우선순위 하나의 표현식에 둘 이상의 연산자가 있는 경우, 실행 순서는 연산자의 우선순위에 의해 결정된다.  하지만 이러한 연산자 우선순위를 무력화 시킬 수 있는 방법이 있다.  (...)를 사용하면 자바