객체 리터럴 축약표현


let name = "devhun";
let isHandsome = true;

const player = {
  name,
  isHandsome,
};

  • ES6 부터는 프로퍼티 값으로 사용할 변수명을 그대로 프로퍼티 키로 사용할 수 있습니다.




계산된 프로퍼티 이름


const prefix = "devhun";
let i = 0;

const obj = {};

obj[`${prefix}_${i}`] = i++;
obj[`${prefix}_${i}`] = i++;
obj[`${prefix}_${i}`] = i++;

const prefix = "devhun";
let i = 0;

// ES6 부터 사용 가능
const obj = {
  [`${prefix}_${i}`]: i++,
  [`${prefix}_${i}`]: i++,
  [`${prefix}_${i}`]: i++,
};

  • ES6 부터는 위와같이 프로퍼티 키로 사용할 값을 표현식을 이용해 동적으로 생성할 수 있습니다.




단축 평가


단축 평가 표현식 평가 결과
true || anything true
false || anything anything
true && anything anything
false && anything false

  • 단축 평가는 위 표에서 본것 같이 논리곱(&&), 논리합(||) 표현식을 평가하는 도중에 평가 결과가 확정된 경우 나머지 평가 과정을 생략하는 것을 말합니다.




논리곱(&&)과 논리합(||)의 단축 평가 원리


// 논리합 연산자
"Cat" || "Dog"; // "Cat"
false || "Dog"; // "Dog"
"Cat" || false; // "Cat"

// 논리곱 연산자
"Cat" && "Dog"; // "Dog"
false && "Dog"; // false
"Cat" && false; // false

  • 논리곱(&&)과 논리합(||)은 좌항에서 우항으로 표현식을 평가합니다. 그리고 논리 연산의 결과를 결정짓는 피연산자를 return 합니다.




단축 평가와 객체


// 논리곱(&&) 응용
const player = null; // or undefined

// player가 null 또는 undefined일 경우 프로퍼티에 접근하지 않음
const name = player && player.name;

// 논리합(||) 응용
function getStringLength(str) {
  //null 또는 undefined로 인한 에러 방지
  str = str || "";
  return str.length;
}

  • 위와 같은 방식으로 단축 평가를 응용할 수 있습니다.




옵셔널 체이닝 연산자


const player = null;

// name은 undefined
const name = player?.name;

  • ?. 좌항의 연산자가 null 또는 undefined일 경우 undefined를 return

  • 논리합(&&) 연산자는 좌항이 Falsy라면 좌항을 return 하지만 ?. 연산자는 오로지 null 또는 undefined일 경우에만 우항을 return 합니다.




null 병합 연산자


function sayHello(name) {
  name = name ?? "default";
  console.log(`${Hello} name`);
}

  • null 병합 연산자는 좌항이 null 또는 undefined일 경우 우항을 return 하고 반대로 우항이 null 또는 undefined일 경우 좌항을 return 합니다. 위와 같은 방법으로 논리곱(||) 연산자를 대신하여 변수에 대한 default 값을 설정할 수 있습니다. ( 논리곱(||)은 Falsy일 경우 우항을 return 하는데 Falsy도 로직에서 유효한 값일 경우 문제가 되기 때문에 null 병합 연산자를 사용하는 것이 좋습니다. )




타입 변환과 값의 불변성

 

  • 원시 값은 불변성의 특징을 가지기 때문에 변수가 가리키는 메모리의 원시 값을 변경하거나 타입을 변경할 수 없습니다. 즉, 타입 변환이란 기존 원시 값을 사용해 다른 타입의 새로운 원시 값을 생성하는 것입니다.




암시적 타입 변환 ( implicit coercion )

 

// 숫자 타입
0 + ""; // "0"
1 + ""; // 1
NaN + ""; // "NaN"

// boolean 타입
true + ""; // "true"
false + ""; // "false"

// null 타입
null + ""; // "null"

// undefined 타입
undefined + ""; // "undefined"

// 객체 타입
({} + ""); // "[object object]"
[10, 20] + ""; // "10, 20"

 

  • 암시적 타입 변환이란 개발자 의도와는 상관없이 자바스크립트 엔진에 의해 값의 타입이 암시적으로 타입이 자동 변환되는 것을 말합니다.




명시적 타입 변환 ( explicit coercion )

 

String(NaN); // "NaN"

(10).toString(); // "10"

Number("0"); // 0

parseInt("12"); // 10

parseFloat("10.53"); // 10.53

Boolean("x"); // true

Boolean(""); // false

 

  • 명시적 타입 변환이란 개발자 의도에 따라 값의 타입이 다른 타입으로 변환하는 것을 말합니다.

  • 명시적 타입 변환 방법은 new를 사용하지 않고 생성자 함수를 호출하거나 빌트인( built-in ) 함수를 이용한 방법이 있습니다.




Truthy / Falsy

 

  • 자바스크립트는 조건식에서 사용하는 Boolean 타입이 아닌 값을 Truthy( 참으로 펴가되는 값 ) 또는 Falsy( 거짓으로 평가되는 값 )으로 구분합니다. 즉, 조건식과 같이 Boolean으로 평가되어야 할 문맥에서 Truthy는 true, Falsy는 false로 암시적 타입 변환됩니다.




Falsy

 

if (false);

if (undefined);

if (null);

if (0 && -0);

if (NaN);

if ("");
  • 위의 값들은 모두 false로 평가되는 값들입니다. 위 값들을 제외하고는 모두 Truthy입니다.




자바스크립트 비교 연산자

 

비교 연산자 의미 사례 설명
== 동등 비교 x == y x와 y의 값이 같음
=== 일치 비교 x === y x와 y의 값과 타입이 같음
!= 부동등 비교 x != y x와 y의 값이 다름
!=== 불일치 비교 x !== y x와 y의 값과 타입이 다름

 

  • 자바스크립트는 동등 비교, 일치 비교라는 두 가지 비교 연산자가 있습니다. 두 연산자 좌,우 항을 비교하여 같은 값으로 평가되면 true 아니면 false를 반환합니다. 하지만 비교의 엄격성 정도가 다르며 동등 비교는 느슨한 비교를 의미하며, 일치 비교는 엄격한 비교를 의미합니다.




동등 비교

 

// true
5 == 5;

// true
5 == "5";

 

  • 동등 비교 연산자는 좌항과 우항의 피연산자를 비교할 떄 먼저 암묵적 타입 변환을 통해 타입을 일치시킨 후 같은 값인지 비교합니다. 따라서 동등 비교 연산자는 좌항과 우항의 피연산자가 타입은 다르더라도 암묵적 타입 변환 후에 같은 값일 경우 true를 반환합니다.




동등 비교 연산자의 문제점

 

// false
"0" == "";

// true
0 == "";

// true
0 == "0";

// true
false == "0";
  • 동등 비교 연산자는 편리한 경우도 있지만 결과를 예측하기 어렵고 실수하기 쉽습니다. 따라서 동등 비교 연산자는 사용하지 않는 편이 좋습니다.




일치 비교

 

  • 일치 비교 연산자는 좌항과 우항의 피연산자가 타입도 같고 값도 같은 경우에 한하여 true를 반환합니다. 즉, 동등 비교 연산자처럼 암묵적 타입 변환을 하지 않고 값을 비교합니다.




일치 비교 연산자의 한 가지 예외

 

// false
NaN === NaN;

// true
Number.isNaN(NaN);

// true
0 === -0;

 

  • 일치 비교 연산자에서 유일하게 NaN과 NaN을 일치 비교 연산자 사용 시 false를 return 합니다. 그렇기 때문에 Number.isNaN(NaN);을 통해서 비교해야 합니다.




자바스크립트 데이터 타입

 

 

  • 자바스크립트는 7가지의 데이터 타입을 가지고 있고 원시 타입과 객체 타입으로 분류할 수 있습니다.




원시 타입

 

  • 원시 값은 변경 불가능한 값입니다.

 

  • 원시 값을 변수에 할당하면 변수에는 실제 값이 저장됩니다.

 

  • 원시 값을 갖는 변수를 다른 변수에 할당하면 원본의 원시 값이 복사되어 전달되며 이를 값에 의한 전달( Pass by value )라고합니다.




객체 타입

 

  • 객체 값은 변경 가능한 값입니다.

 

  • 객체를 변수에 할당하면 변수에는 참조 값이 저장됩니다.

 

  • 객체 값을 갖는 변수를 다른 변수에 할당하면 원본의 참조 값이 복사되어 전달되며 이를 참조에 의한 전달( Pass by reference )라고 합니다.




숫자 타입

 

// 정수
let integer = 10;

// 실수
let double = 10.12;

// 음의 정수
let negative = -20;

// true를 출력
console.log(1 === 1.0);

 

  • 자바스크립트의 숫자 타입은 배정밀도 64bit 부동소수점 형식을 따릅니다. 모든 수를 실수로 처리하며, 정수만 표현하기 위한 데이터 타입이 별도로 존재하지 않습니다.




숫자 타입의 특별한 값

// Infinity 출력
console.log(10 / 0);

// -Infinity 출력
console.log(10 / -1);

// NaN 출력
console.log(1 * "Hello World");

 

  • Infinity : 양의 무한대

 

  • -Infinity : 음의 무한대

 

  • NaN( Not a Number ) : 산술 연산 불가




문자열 타입

 

let name = "devhun";

name = 'devhun';

console.log(`My name is ${name}`);

 

  • 문자열 타입은 텍스트 데이터를 나타내는 데 사용하며 16bit 유니코드 문자 집합을 사용합니다. 문자열 표현 방법으로는 "" or '' or ``으로 문자열을 표현할 수 있습니다.

 

표현식 삽입

 

const name = "devhun";

console.log(`Hello ${name}`);

 

  • ``을 사용해서 위와같이 변수를 문자열 중간에 삽입할 수 있습니다.




boolean 타입

 

let isLogin = true;

if (isLogin === false) {
  console.log("Login Failed");
}
  • true, false를 이용한 참, 거짓을 표현할 수 있습니다.




undefined

 

  • undefined는 자바스크립트 엔진이 var 데이터 타입을 초기화할 때 사용하는 값입니다.

 

  • 프로그래머가 직접 undefined를 대입을 고려해야할 때는 undefined 보다는 null을 할당하는 것이 낫습니다.




null

 

  • null은 변수의 값이 없다는 것을 명시할 때 사용하는 값입니다.




심볼 타입

 

const sym = Symbol();

let obj = {};

obj[sym] = "devhun";

console.log(obj[sym]);

 

  • 심볼 타입은 ES6에 추가된 타입으로서 변경 불가능한 원시 타입의 값입니다. 심볼은 다른 값과 중복되지 않는 유일무이한 값입니다. 주로 이름이 충돌할 위험이 없는 객체의 유일한 프로퍼티 키를 만들기 위해 사용합니다.
    심볼 이외의 원시 값은 리터럴을 통해 생성하지만 심볼은 Symbol 함수를 호출해 생성합니다. 생성된 심볼은 외부에 노출되지 않으며 다른 값과 절대로 중복되지 않는 유일무이한 값입니다.




자바스크립트의 값의 할당( Variable Assignment )

 

var number1 = 30;

var number2;
number2 = 20;

 

  • 자바스크립트에서 위 코드에서 보여주는 두 개의 할당 방식은 선언과 할당으로 분리되어 동일한 코드로 해석됩니다. ( 자바스크립트에서 var 변수 선언은 변수에 대한 정보를 자바스크립트에 알려주고 메모리를 확보하여 undefined로 초기화까지 진행합니다.)

 

  • 할당문이 실행되기 이전에 이미 undefined로 초기화되어 있기 때문에 할당문이 실행될 경우 할당값의 메모리를 새롭게 확보하여 변수가 해당 메모리를 참조할 수 있도록합니다.




자바스크립트의 값의 재할당

 

 

var number = 10;
number = 1000;

 

  • 자바스크립트 엔진은 var 변수 초기화값으로 undefined가 저장된 메모리를 참조하도록 하기 때문에 모든 var 변수 대입은 재할당입니다.
    자바스크립트에서 변수를 재할당할 경우 기존에 가리키던 메모리는 자바스크립트 엔진의 가비지 컬렉터에 의해서 언젠가는 해제됩니다.




자바스크립트의 변수 선언( Variable Declaration )

 

var number;

console.log(number);
  • 자바스크립트에서 선언은 자바스크립트 엔진에게 변수에 대한 정보를 알려주고 메모리 확보를 진행합니다. 그리고 var타입의 경우는 undefined로 초기화까지 수행합니다.




변수 호이스팅( Variable Hoisting )이란?

 

// undefined 출력
console.log(num1);

{
  var num1;
}
  • 자바스크립트는 인터프리터 언어로서 모든 코드를 맨 위에서 한 줄씩 실행되기 때문에 위 코드는 정상적으로 수행되지 않을것 처럼 보이지만 실제로는 undefined를 출력합니다.
    자바스크립트 엔진은 런타임(runtime) 이전에 변수 선언을 포함한 모든 선언문을 소스코드에서 찾아내 먼저 실행 후 각 선언문들을 자신이 속한 스코프 레벨의 최상단으로 끌어 올려진 것처럼 동작하는데 이러한 자바스크립트 고유의 특징을 변수 호이스팅이라고 합니다.
    ( var 데이터 타입은 함수 레벨 스코프만 인식하기 때문에 블록 레벨 스코프는 무시합니다. )




값, 리터럴, 표현식, 문 구별이 중요한 이유


  • 값, 리터럴, 표현식, 문을 구별함으로서 코드를 읽고 실행 결과를 예측할 수 있으며, 이는 버그를 줄이고 코드의 품질을 높여주는데 도움이 됩니다. 또한 이러한 용어를 정확하게 습득함으로서 협업하는 과정에서 의사소통 비용을 줄일 수 있습니다.




값( value )란?


  • 값은 식( 표현식 ) 또는 리터럴( literal )이 평가되어 생성된 결과를 말합니다.




평가란?


// 10 + 20을 평가해서 30을 생성
let num = 10 + 20;

  • 평가란 위와같은 식을 해석해서 값을 생성하거나 참조하는 것을 의미합니다.




리터럴( literal )


  • 리터럴은 사람이 이해할 수 있는 문자 또는 약속된 기호를 사용해 값을 생성하는 표기법을 말합니다.

  • 자바스크립트 엔진은 코드가 실행되는 시점인 런타임에 리터럴을 평가해 값을 생성합니다.

리터럴 종류

리터럴
예시
비고
정수 리터럴 200
부동소수점 리터럴 20.5
2진수 리터럴 0b00010001 0b로 시작
8진수 0o101 ES6에서 도입. 0o로 시작
16진수 0x41 ES6에서 도입. 0x로 시작
문자열 리터럴 "Hello", 'World'
불리언 리터럴 true, false
null 리터럴 null
undefined 리터럴 undefined
객체 리터럴 {name:"devhun", address :"seoul"}
배열 리터럴 [1,2,3]
함수 리터럴 function() {}
정규 표현식 리터럴 /[A-Z]+/g




표현식( expression )


  • 표현식은 값으로 평가될 수 있는 문( statement )입니다.

  • 표현식이 평가되면 새로운 값을 생성하거나 기존 값을 참조합니다.




리터럴( literal )과 표현식


var isHandsome = true;

  • 위 표현식에서 true 리터럴은 값으로 평가되며 결국 위의 식은 표현식입니다.




문( statement )


  • 문( statement )은 프로그램을 구성하는 기본 단위이자 최소 실행 단위입니다. 문의 집합으로 이뤄진 것이 바로 프로그램이며, 문을 순서에 맞게 작성하며 나열하는 것이 프로그래밍입니다. 문은 명령문이라고도 부르며 자바 스크립트 엔진은 세미콜론을 통해 문의 종료를 파악하고 이를통해 하나씩 문을 실행합니다.




문의 종류


// 선언문
let x;

// 할당문
x = 5;

// 함수 선언문
function foo() {}

// 조건문
if (x > 3) console.log(x);

// 반복문
for (let i = 0; i < 10; ++i) console.log("Hello World");

  • 문은 명령문이라고도 부릅니다. 즉, 문은 컴퓨터에 내리는 명령이며 문의 종류로는 선언문, 할당문, 조건문 반복문 등으로 구분할 수 있습니다.




표현식인 문과 표현식이 아닌 문


// 선언문은 값으로 평가될 수 없으므로 표현식이 아니다.
let x;

// 1 + 2는 값으로 평가되기 때문에 표현식이면서 문이다.
x = 1 + 2;

// 선언문은 변수에 할당할 수 없다.
let z = let y;

// 표현식인 문은 값처럼 사용할 수 있다.
let i = x = 1000;
  • 표현식은 문의 일부일 수도 있고 그 자체로 문이 될 수도 있다. 표현식인 문은 변수에 할당이되고 표현식이 아닌 문은 변수에 할당이 안 된다.




volatile 키워드란?

 

  • volatile 키워드는 volatile 키워드를 사용한 변수에 대한 컴파일 최적화에서 제외시키기 위해 사용하는 키워드입니다.




컴파일 최적화란?

 

  • 컴파일러가 프로그래머가 작성한 소스 코드를 컴파일 할 때 불필요한 코드를 개선하거나 제거하여 성능 및 메모리 사용량을 최적화하는 기능을 말합니다.




volatile 키워드와 최적화 컴파일 on/off

 

 

  • 컴파일 옵션에서 최적화 컴파일 '사용 안 함'으로 설정할 경우 모든 코드를 대상으로 컴파일 최적화를 수행하지 않기 때문에 컴파일 최적화를 끈 환경에서는 volatile 키워드는 어떤 기능도 수행하지 않습니다.




volatile과 비순차적 명령어 처리( OOOE : Out-of-order Execution )

 

  • 컴파일러 최적화에 의한 명령어 코드 최적화랑 CPU가 명령어 파이프라인의 최적화를 위해서 사용하는 OOOE는 서로 완전히 다른 기능입니다. 컴파일 최적화는 컴파일러가 진행하고 OOOE는 CPU 내부에서 제공하는 기능이기 때문에 volatile을 사용한다고 해서 OOOE를 막을 수는 없습니다.




volatile 키워드를 사용하는 이유

 

최적화된 코드

 

volatile 키워드 사용한 코드

 

  • 컴파일 최적화로 인해서 이전에 레지스터에 저장된 주소를 재활용하여 명령어를 수행하거나 멀티 쓰레드 환경이나 임베디드 환경에서 프로그래머가 의도하지 않는 로직으로 수행될 수 있기 때문에 필요에 따라서 volatile을 사용해야합니다.




자바스크립트( JavaScript )란?


  • 자바스크립트(영어: JavaScript)는 객체 기반의 인터프리터 언어입니다. 현재는 컴파일 언어의 특징 일부를 가지고 있습니다.




간단한 자바스크립트 문법


const player = {
  name: "devhun",
  age: 20,
  isHandsome: true,
};

console.log(player.name);
  • 위 코드는 자바스크립트를 통해 객체를 생성하는 문법입니다.




자바스크립트 탄생 비화


  • 1995년, 약 90%의 시장 점유율로 웹 브라우저 시장을 지배하고 있던 넷스케이프 커뮤니케이션즈는 웹 페이지의 보조적인 기능을 수행하고 인터랙티브하게 만들기 위해 브라우저에서 동작하는 경량 프로그래밍 언어를 도입하기로 결정하였고 그래서 탄생한 것이 바로 브랜든 아이크 ( Brendan Eich ) 가 10일 만에 개발한 자바스크립트입니다.




자바스크립트 표준화


  • 자바 스크립트의 파편화 방지 및 모든 브라우저에서 정상적으로 동작하는 표준화된 자바스크립트를 위해서 1996년 11월, 넷스케이프 커뮤니케이션즈는 컴퓨터 시스템의 표준을 관리하는 비영리 표준화 기구인 ECMA( European Computer Manufacturers Association ) 인터내셔널에 자바스크립트의 표준화를 요청 후
    1997년 7월, ECMA-262라 불리는 표준화된 자바스크립트(ECMAScript 1) 사양이 완성되었고 상표권 문제로 "ECMAScript로" 명명되었습니다. 이후 1999년 "ECMAScript 3( ES3 )" 이 공개된 이후 ES5, ES6 등이 출시되었습니다.




자바스크립트 성장의 역사


  • 초창기 자바스크립트는 웹페이지의 보조적인 기능을 수행하기 위해 한정적인 용도로 사용되었습니다. 2008년에 구글이 V8 자바스크립트 엔진을 출시하면서 훨씬 좋은 퍼포먼스를 가진 자바스크립트 엔진을 선보였으며 이는 자바스크립트가 더욱 발전할 수 있는 계기가 되었습니다.




Node.js


  • Node.js는 2009년 "라이언 달 ( Ryan Dahl )" 이 발표한 Node.js는 브라우저의 자바스크립트 엔진에서만 동작하던 자바스크립트를 브라우저 이외의 환경에서도 동작할 수 있도록 구글의 V8 자바스크립트 엔진으로 빌드된 자바스크립트 런 타임입니다.

    Node.js는 다양한 플랫폼에 적용할 수 있지만 서버 사이드 애플리케이션 개발에 주로 사용되며 이에 필요한 모듈, 파일 시스템, HTTP 등 빌트인 API를 제공합니다.

    Node.js의 등장으로 자바스크립트는 브라우저를 벗어나 서버 사이드 애플리케이션 개발에서도 사용할 수 있는 범용 프로그래밍 언어가 되었으며, 현재는 크로스 플랫폼을 위한 가장 중요한 언어로 주목받고 있습니다.




자바스크립트와 ECMAScript



  • ECMAScript는 자바스크립트 표준 사양인 ECMA-262를 말하며, 프로그래밍 언어의 값, 타입, 객체와 프로퍼티, 함수, 표준 빌트인 객체 등 핵심 문법을 규정한 것을 말합니다. 각 브라우저 제조사는 ECMAScript 사양을 준수해서 브라우저에 내장되는 자바스크립트 엔진을 구현합니다.

    자바스크립트는 일반적으로 프로그래밍 언어로서 기본 뼈대를 이루는 ECMAScript와 브라우저가 별도 지원하는 클라이언트 사이드 Web API, 즉 DOM, BOM, Canvas, XMLHttpRequest, fetch, requestAnimationFrame, SVG, Web Storage, Web Component, Web Worker 등을 아우르는 개념입니다.

    클라이언트 사이드 Web API는 ECMAScript와는 별도로 W3C( World Wide Web Consortium )에서 별도의 사양으로 관리하고 있습니다.




+ Recent posts