변수

자바스크립트에서 변수를 선언할 때 사용하는 키워드에는 var, let, const가 있다.

각 키워드는 변수의 스코프와 재할당 가능성, 호이스팅 방식에서 차이가 있다.

 

var

함수 스코프

var로 선언된 변수는 함수 스코프를 가지며 함수 내에서 선언된 변수는 함수 전체에서 접근할 수 있다.

 

호이스팅

var로 선언된 변수는 호이스팅 되며 선언이 코드의 최상단으로 끌어올려지고 초기화는 선언한 위치에서 이루어진다.

 

변수 재선언 가능

같은 스코프 내에서 여러 번 선언할 수 있다. 이때 이전 값은 덮어씌워지게 된다.

 

전역 객체에 속성으로 추가

전역 스코프에서 선언된 var변수는 전역 객체의 속성이 된다. (global 또는 window)

 

console.log(x); // undefined (호이스팅)
var x = 5;
console.log(x); // 5

if (true) {
  var y = 10;
}
console.log(y); // 10 (블록 스코프가 아님)

function foo() {
  var z = 20;
  console.log(z); // 20
}
foo();
// console.log(z); // ReferenceError: z is not defined (함수 스코프)

 

let 

블록스코프

let으로 선언된 변수는 블록 스코프를 가지고 블록 내에서만 접근할 수 있다.

 

호이스팅

let으로 선언된 변수는 호이스팅 되지만 선언하기 전에는 사용할 수 없으며 이를 '일시적 사각지대(TDZ, Temporal Dead Zone)'이라고 한다.

 

변수 재선언 불가

같은 스코프 내에서 두 번 선언할 수 없다.

// console.log(a); // ReferenceError: Cannot access 'a' before initialization (TDZ)
let a = 5;
console.log(a); // 5

if (true) {
  let b = 10;
  console.log(b); // 10
}
// console.log(b); // ReferenceError: b is not defined (블록 스코프)

let c = 15;
// let c = 20; // SyntaxError: Identifier 'c' has already been declared (재선언 불가)

 

const

블록스코프

const로 선언된 변수는 블록 스코프를 가진다.

 

호이스팅

const로 선언된 변수는 호이스팅 되지만, 선언하기 전에는 사용할 수 없다. TDZ에 영향을 받는다.

 

변수 재선언 불가

같은 스코프 내에서 두 번 선언할 수 없다.

 

상수

const로 선언된 변수는 초기화 후에 값을 변경할 수 없지만 객체나 배열의 속성은 변경할 수 있다.

 

// console.log(d); // ReferenceError: Cannot access 'd' before initialization (TDZ)
const d = 5;
console.log(d); // 5

if (true) {
  const e = 10;
  console.log(e); // 10
}
// console.log(e); // ReferenceError: e is not defined (블록 스코프)

const f = 15;
// const f = 20; // SyntaxError: Identifier 'f' has already been declared (재선언 불가)

// f = 25; // TypeError: Assignment to constant variable. (값 변경 불가)

const obj = { key: "value" };
obj.key = "new value"; // 객체의 속성은 변경 가능
console.log(obj.key); // "new value"

const arr = [1, 2, 3];
arr.push(4); // 배열의 요소는 추가 가능
console.log(arr); // [1, 2, 3, 4]
728x90
반응형

'Program Language > JavaScript' 카테고리의 다른 글

JavaScript #6 호이스팅(Hoisting)  (0) 2024.07.21
JavaScript #5 유효 범위, 스코프(Scope)  (0) 2024.07.21
JavaScript #3 연산자  (1) 2024.07.21
JavaScript #2 표현식  (0) 2024.07.21
JavaScript #1 개요  (0) 2024.07.21

연산자 기호는 공통적으로 사용되는 사칙연산을 적용하고 있다.

그 밖에 추가로 사용되는 연산자 중 차이점을 정리한다.

 

비교 연산자

동등 연산자와 일치 연산자

true == 1;
// true , 두 피연산자를 비교하기 전에 true를 1로 변환
true === 1;
// false , 두 피연산자의 타입부터 비교된다.

 

비슷해 보이는 두 연산자의 동일한 값 비교에서 명확한 차이가 난다.

 

 

'==' 동등 연산자

비교하는 두 값의 타입이 다르면 비교하기 전에 타입을 동일하게 변환 후 비교를 한다.

console.log(5 == '5');      // true, 숫자 5와 문자열 '5'가 타입 강제 변환 후 비교
console.log(null == undefined); // true, 둘 다 비어있는 값을 나타냄
console.log(0 == false);    // true, 숫자 0과 불리언 false가 타입 강제 변환 후 비교
console.log('' == false);   // true, 빈 문자열과 불리언 false가 타입 강제 변환 후 비교

 

'===' 일치 연산자

타입과 값이 모두 동일해야만 참을 반환한다.

console.log(5 === '5');     // false, 타입이 다르므로 일치하지 않음
console.log(null === undefined); // false, 타입이 다르므로 일치하지 않음
console.log(0 === false);   // false, 타입이 다르므로 일치하지 않음
console.log('' === false);  // false, 타입이 다르므로 일치하지 않음
console.log(5 === 5);       // true, 타입과 값이 모두 동일

 

타입 강제 변환의 수행 때문에 예기치 않은 결과를 발생시킬 수 있다. 따라서 자바스크립트에서는 일관성과 예측 가능한 동작을 위해 일반적으로 '==='를 사용하는 것이 권장된다.

 

<, > 등호 

숫자뿐만 아니라 문자열과 객체도 비교가 가능하다. 

console.log(5 < 10);   // true
console.log(5 > 10);   // false
console.log(10 > 10);  // false
console.log(10 < 10);  // false
console.log(10 <= 10); // true
console.log(10 >= 10); // true

 

 

문자열 비교는 유니코드 값을 기준으로 문자열을 비교한다.

console.log('apple' < 'banana');   // true
console.log('grape' > 'banana');   // true
console.log('apple' > 'Apple');    // true ('a'의 유니코드 값이 'A'보다 큼)
console.log('2' < '10');           // false (문자열 비교에서 '2'는 '10'보다 큼)

 

객체의 경우 직접 등호를 사용해서 비교할 수 없지만 비교 시 객체를 원시 값으로 변환하려고 시도한다. 이 경우 두 객체의 참조를 비교한다. 일반적으로 객체의 비교는 특정 속성을 비교하는 방법으로 사용한다.

// 객체 직접 비교시
let obj1 = { value: 10 };
let obj2 = { value: 20 };

console.log(obj1 < obj2); // false
console.log(obj1 > obj2); // false
console.log(obj1 == obj2); // false

// 객체의 속성 비교
let obj1 = { value: 10 };
let obj2 = { value: 20 };

console.log(obj1.value < obj2.value); // true

 

숫자와 문자열간의 비교도 가능하며 이 경우 자동으로 타입을 변환하여 비교한다.

console.log('5' < 10);  // true (문자열 '5'는 숫자 5로 변환됨)
console.log('5' > 10);  // false
console.log('5' > '10'); // true ('5'와 '10'은 문자열로 비교됨, '5'는 '10'보다 큼)

 

in 연산자

객체의 속성이나 배열의 인덱스가 존재하는지 확인하는 데 사용된다.

 

객체의 특정 속성이 존재하는지 확인할 때

let person = {
  name: "Alice",
  age: 30
};

console.log("name" in person); // true
console.log("age" in person);  // true
console.log("gender" in person); // false

 

배열의 특정 인덱스가 존재하는지 확인할 때

let numbers = [10, 20, 30];

console.log(0 in numbers); // true
console.log(1 in numbers); // true
console.log(3 in numbers); // false (인덱스 3은 존재하지 않음)

 

in 연산자는 주어진 속성 또는 인덱스가 객체의 자체 속성인지, 프로토타입 체인에 속한 속성인지 여부를 검사한다.

let person = {
  name: "Alice"
};

console.log("toString" in person); // true, toString은 Object.prototype의 속성

 

toString은 person 객체에 직접 정의된 속성이 아니지만 Object.protorype에 정의된 속성이기 때문에 in 연산자는 true를 반환한다.

 

객체의 자체 속성만을 검사하려면 Object.hasOwnProperty 메서드를 사용한다.

let person = {
  name: "Alice"
};

console.log(person.hasOwnProperty("name")); // true
console.log(person.hasOwnProperty("toString")); // false

 

instanceof 연산자

특정 객체가 특정 생상저 함수 또는 클래스의 인스턴스인지 확인하는 데 사용된다. 이를 통해 객체의 프로토타입 체인을 검사하여 객체가 특정 생성자 함수의 프로토타입을 상속받았는지 여부를 확인할 수 있다.

object instanceof Constructor

 

여기서 object는 검사할 객체, Constructor는 생성자 함수이다.

 

원시 타입인 숫자, 문자열, 불리언 등에는 사용할 수 없다.

console.log(5 instanceof Number); // false
console.log("hello" instanceof String); // false

 

instanceof 연산자는 객체의 프로토타입 체인을 따라가면서 주어진 생성자 함수의 prototype 속성과 일치하는 프로토타입이 있는지 검사한다. 이 과정은 객체의 프로토타입 체인 끝에 도달할 때까지 계속된다.

 

function Foo() {}
function Bar() {}

let foo = new Foo();

console.log(foo instanceof Foo); // true
console.log(foo instanceof Bar); // false
console.log(foo instanceof Object); // true (Foo의 인스턴스는 Object의 인스턴스이기도 함)

 

따라서 객체의 프로토타입이 동적으로 변경된다면 instanceof의 결과도 달라질 수 있게 된다.

function Foo() {}
function Bar() {}

let obj = new Foo();
console.log(obj instanceof Foo); // true

Object.setPrototypeOf(obj, Bar.prototype);
console.log(obj instanceof Foo); // false
console.log(obj instanceof Bar); // true

 

typeof 연산자

typeof 연산자는 데이터 타입을 검사하는 데 사용되며 주로 원시 타입을 검사할 때 사용한다.

console.log(typeof 5);          // "number"
console.log(typeof "hello");    // "string"
console.log(typeof true);       // "boolean"
console.log(typeof {});         // "object"
console.log(typeof []);         // "object"
console.log(typeof function(){}); // "function"

 

논리 연산자

논리적인 조건을 평가하거나 결합하는 데 사용된다. 주로 조건문에서 사용되며 참 또는 거짓 값을 반환한다.

 

&& AND

두 피연산자가 모두 참일 때 참, 하나라도 거짓이면 거짓을 반환한다.

console.log(true && true);   // true
console.log(true && false);  // false
console.log(false && true);  // false
console.log(false && false); // false

let a = 5;
let b = 10;
console.log(a > 0 && b > 0); // true (a와 b가 모두 0보다 큼)

 

|| OR

두 피연산자 중 하나라도 참이면 참, 둘 다 거짓일 때만 거짓을 반환한다.

console.log(true || true);   // true
console.log(true || false);  // true
console.log(false || true);  // true
console.log(false || false); // false

let a = 5;
let b = -10;
console.log(a > 0 || b > 0); // true (a가 0보다 큼)

 

! NOT

피연산자의 부정을 반환한다. 참이면 거짓, 거짓이면 참을 반환한다.

console.log(!true);  // false
console.log(!false); // true

let a = 5;
console.log(!(a > 0)); // false (a > 0은 true이므로, !true는 false)

 

 

논리 연산자의 단축 평가 (Short-Circuit Evaluation)

논리 연산자는 단축 평가를 사용하여 불필요한 연산을 피한다. 이는 첫 번째 피연산자가 전체 표현식의 결과를 결정할 수 있는 경우 두 번째 피연산자를 평가하지 않는다는 것을 의미한다.

 

&&, 첫 번째 연산자가 거짓이면 두 번째 피연산자를 평가하지 않는다.

console.log(false && true);  // false (두 번째 피연산자를 평가하지 않음)
console.log(true && false);  // false
console.log(false && false); // false (두 번째 피연산자를 평가하지 않음)
console.log(true && true);   // true

let a = 5;
let b = 10;
console.log(a > 0 && b > 0 && b > a); // true (모든 조건이 참)

 

||, 첫 번째 피연산자가 참이면 두 번째 피연산자를 평가하지 않는다.

console.log(true || false);  // true (두 번째 피연산자를 평가하지 않음)
console.log(false || true);  // true
console.log(true || true);   // true (두 번째 피연산자를 평가하지 않음)
console.log(false || false); // false

let a = 5;
let b = -10;
console.log(a > 0 || b > 0 || b < a); // true (첫 번째 조건이 참이므로 나머지 조건을 평가하지 않음)

 

delete 연산자

객체의 속성을 삭제하는 데 사용된다. 주로 객체의 속성만을 삭제할 때 사용한다. 

 

delete object.property;
//또는
delete object['property'];

 

객체의 특정 속성을 삭제하고 삭제된 속성은 객체에서 완전히 제거되어 더 이상 해당 속성에 접근할 수 없다.

 

let person = {
  name: "Alice",
  age: 30
};

console.log(person.age); // 30

delete person.age; // age 속성 삭제

console.log(person.age); // undefined (삭제된 속성에 접근 시)
console.log(person); // { name: "Alice" }

 

배열의 요소 삭제

배열의 요소를 삭제할 수 있지만 배열의 길이는 변경되지 않고 해당 인덱스는 undefined로 남아 있게 되므로 완전히 제거하고 길이를 줄이기 위해서는 splice 메서드를 사용하는 것이 좋다.

 

let numbers = [1, 2, 3, 4];

delete numbers[2]; // 배열의 세 번째 요소 삭제

console.log(numbers); // [1, 2, undefined, 4]
console.log(numbers.length); // 4 (배열 길이는 그대로)

 

프로토타입 속성 삭제

객체의 프로토타입에 정의된 속성은 delete 연산자로 삭제할 수 없다.

 

function Person(name) {
  this.name = name;
}

Person.prototype.age = 30;

let alice = new Person("Alice");

console.log(alice.age); // 30 (프로토타입 속성)

delete alice.age; // 인스턴스의 age 속성 삭제 시도 (실제로 프로토타입의 속성은 삭제되지 않음)

console.log(alice.age); // 30 (프로토타입의 속성은 여전히 존재)

 

변수 삭제

전역 변수와 함수의 경우 delete 연산자를 사용해도 삭제되지 않는다. 지역 변수는 delete로 삭제할 수 없다.

 

 

728x90
반응형

'Program Language > JavaScript' 카테고리의 다른 글

JavaScript #6 호이스팅(Hoisting)  (0) 2024.07.21
JavaScript #5 유효 범위, 스코프(Scope)  (0) 2024.07.21
JavaScript #4 변수  (1) 2024.07.21
JavaScript #2 표현식  (0) 2024.07.21
JavaScript #1 개요  (0) 2024.07.21

표현식은 코드에서 값으로 평가될 수 있는 코드의 조각이라고 말할 수 있다.

표현식의 결과는 값이 될 수 있으며, 이를 통해 값을 할당하거나 다른 표현식의 일부로 사용할 수 있다.

 

표현식을 파악하면 자바스크립트의 문법이 어떤 코드의 조각들로 작성되어서 변수의 값이 할당되고 조건문 및 반복문 등이 구성되고 함수의 인수로 전달되는지 알 수 있다.

 

표현식 종류

리터럴 표현식

고정된 값을 나타낸다.

가장 간단한 형태로 다른 표현식을 포함하지 않는 독립적인 표현식이다.

1; // 숫자 리터럴
"hello" // 문자열 리터럴
true; //boolean 리터럴
[1,2,3]; // 배열 리터럴
{key:"value"}; // 객체 리터럴

 

식별자 표현식

변수나 상수의 이름을 나타낸다.

let x = 10;
x; // 식별자 표현식 값 : 10

 

 

연산자 표현식

연산자를 사용하여 값을 생성한다.

5 + 5;
x * 2;
y > 5;

 

함수 호출 표현식

함수를 호출하여 값을 생성한다.

function add(a, b){
	return a + b;
}
add(3, 4); // 함수 호출 표현식, 값 : 7

 

객체 프로퍼티 접근 표현식

프로퍼티에 접근하는 표현식이다.

let person = { name : "Bak", age: 25};
person.name; // 객체 프로퍼티 접근 표현식, 값 : "Bak"

 

산술 표현식

let a = 5;
let b = 10;
let sum = a + b; // 값 15

수로 변환 불가능한 피연산자인 경우 NaN(Not-a-Number) 값으로 변환되며 피연산자 중 하나라도 NaN일 경우 연산 결과는 NaN이 된다.

 

비교 표현식

let isEqual = (a === b);

 

논리 표현식

let isAdult = (age >= 25 && age < 100);

 

삼항 표현식

let access = (age >= 18) ? "Adult" : "None";

 

표현식 사용

변수 할당

let result = 5 + 10; // 연산자 표현식을 사용하여 result에 값 할당

 

조건문

let age = 25;
if (age >= 25) { // 비교 연산자 표현식을 사용한 조건문
	console.log("Bakcdoing's Blog");
}

 

함수 인수

fuction greet(name){
	console.log("Hello, " + name);
}
greet("Bak"); // 문자열 리터럴을 함수 인수로 사용
728x90
반응형

'Program Language > JavaScript' 카테고리의 다른 글

JavaScript #6 호이스팅(Hoisting)  (0) 2024.07.21
JavaScript #5 유효 범위, 스코프(Scope)  (0) 2024.07.21
JavaScript #4 변수  (1) 2024.07.21
JavaScript #3 연산자  (1) 2024.07.21
JavaScript #1 개요  (0) 2024.07.21

+ Recent posts