코드 내의 변수, 함수 혹은 속성을 식별하는 문자열
변수 let / 상수 const(객체)
let age = 30;
function setAge() {}
// let / function : 키워드(식별자) / age / setAge: 식별자 / 30 : 데이터값
const obj ={
age:10, //age:key / 10 : value -> key,value값이 있는 것을 객체라고 함
["my name"] : "이름" //공백있는 식별자를 쓰고 싶을 때 [""] "my name"이라고는 X
};
const NATIONALITY = "korea" //상수 대문자로 네이밍
//콘솔
console.log(obj["my name"]) //"이름"
console.log(obj.age) //10
식별자 표기법
1. 카멜케이스(camel case) : 낙타등같은 모양. 첫글자는 소문자로시작하고 이후 각 단어에 첫글자를 대문자로 표기 - 변수, 식별자에서 카멜케이스를 주로 사용 (ex)setAge
2. 스네이크케이스 (snake case) : 모든 단어를 소문자로 표기하고 단어 사이를 언더스코어(_)로 구분한다 (ex)set_age
3. 파스칼케이스 (pascal case) : 각 단어마다 첫 글자가 대문자로 시작(모든글자) (ex)SetAge
4. 케밥케이스 (kebab case) : 모든 단어를 소문자로 표기, 각 단어 사이 하이픈(-)으로 구분 (ex)set-age
const str1 = "hello world"
//const:키워드 / str1:식별자 / "":문자열데이터
const str3 = `hello, ${str2}`;
//`백틱` : `문자열,${상수데이터}` -> 데이터 자체를 문자로 받아서 ${}로 받아서 데이터 출력 -> 문자열로 출력됨
//--> 문자열 리터럴 방식으로 작성
const num3 = -123.5678;
const pi = 3.14; //부동소수점
console.log(num3 + undefined); //출력값 NaN -> 숫자데이터+다른타입 값 연산 -> 연산 자체가 안되서 number가 아니라는 뜻으로 난수 출력
console.log(typeof (num3 + undefined)); //NaN은 숫자데이터 타입이기 때문에, 출력값 number
console.log(typeof pi); //출력값 number
const a = 0.1;
const b = 0.2;
console.log(a+b) //0.30000000000000004
console.log(typeof(a+b).toFixed(1)); //string
// tofixed(1)은 숫자를 소숫점 첫째자리까지 반올림 후 문자열로 변환하여 반환 -> "0.3"인 "string"을 반환함.
console.log(typeof Number((a+b).toFixed(1))); //number -> 문자열로 바뀐 타입을 데이터 Number 타입으로 형변환
console.log(Number((a+b).toFixed(1))); //0.3 (소숫점 첫째짜리까지 출력)
//toFixed함수 : 내장함수. 고정 소수점 표기법을 사용해서 나타낸 수를 문자열로 바꾼 값. 항상 문자열을 반환함.(숫자반환x)
숫자 데이터와 다른 타입의 값을 연산할경우 난수 출력
NaN : not a number. 난수.
데이터는 타입 자체는 숫자 데이터인데 특정한 숫자 값으로 표현 할 수 없기때문에 NaN으로 출력 반환. NaN이라는 값이 나오면 숫자 연산에 숫자가 아닌 다른 값이 포함되어있을 가능성이 있음.
true와 false라는 두가지 값(데이터)만 사용하는 논리데이터
true:긍정 false:부정
const truty = true;
const falsy = false;
if(falsy){
console.log("조건식이 참입니다")
}else {
console.log("조건식이 거짓입니다")
}
if(typeof truty === "string"){
//truty는 boolean타입이기때문에 string타입을 넣으면 오류 -> else값 출력
console.log("조건식이 참입니다")
}else {
console.log("조건식이 거짓입니다")
}
존재하지 않는다 / 값이 비어있다 / 값을 알수없다를 명시적으로 표현. 의도적으로 변수를 비우거나 특정 상황에서 값이 없음을 나타내기 위해 사용
let value1 = null;
//value1이라는 초기값에 의도적으로 null이라는 데이터를 삽입(의도O)
console.log(value1) //null
console.log(typeof value1) //object
//null타입은 object(객체)타입의 데이터가 있는지 없는지 사용됨 -> 그래서 typeof로 출력할 때 object 출력
변수가 선언되었지만 값이 할당되지 않았음을 의미.
값 자체가 아예 존재하지 않는다.
함수가 값을 반환하지 않을 때 / 객체에서 존재하지 않는 속성에 접근했을때 undefined 반환
setTimeout(() => { //setTimeout : 딜레이 함수 (1초 뒤에 출력) -> 비동기함수
value1 = 30;
console.log(value1) //30
}, 1000)
let value2; //값이 아무것도 들어있지 않음 let value2 = "값(x)"
console.log(value2) //undefined
const user = {
name : "data",
age: 999,
}
console.log(user.name)
console.log(user.age)
console.log(user.email) //undefined -> 객체데이터에 참조할 값이 없음
null과 undefined의 차이?
둘다 값이 비어있지만 null은 의도적으로 값이 비었음을 표현. null을 변수에 할당할때는 신중해야한다.
const fruits01 = new Array("사과", "바나나", "딸기");
console.log(fruits01); //(3) ['사과', '바나나', '딸기']
const fruits02 = ["사과", "바나나", "딸기", "수박"]; //[배열데이터]
console.log(fruits02); //(4) ['사과', '바나나', '딸기', '수박']
console.log(fruits02[1]); //바나나 -> 배열데이터 인덱싱 / 배열의 index번호는 0번부터 시작하기때문에 index 1(2번째 데이터인 바나나)
console.log(fruits02.length); //4 -> length:배열데이터의 길이(요소가 4개)
console.log(fruits02[fruits02.length - 1]); //4(배열데이터의 길이 fruits02.length)-1 = 3 -> index번호가 3인데이터 -> 수박 = 배열의 길이-1 = 해당 배열의 가장 마지막 요소를 조회
console.log(fruits02[0]); //사과
const user01 = new Object();
user01.name = "이름"; //user01.name : key / "이름" : value
user01.age = 99;
user01.job = "programmer";
console.log(user01);
const user02 = {
name: "이름",
age: 99,
job: "programmer",
};
console.log(user02);
console.log(user02.name); //객체에서는 .표기법으로 접근
console.log(user02["job"]); //대괄호표기법
//일반적으로 .표기법 사용 / 속성이름이 동적이거나 공백, 특수문자 포함된 경우 대괄호표기법 사용
const user03 = {
name: "이름03",
age: 100,
job: "student",
};
const user04 = {
name: "이름04",
age: 10,
brother: user03, //객체 안에 또 다른 객체를 할당
};
console.log(user04.brother); //user03이 출력된다.
console.log(user04.brother.name); //user03의 name이 출력된다.
console.log(user04.brother["job"]); //user03의 job이 출력된다.
const family = [user03, user04];
console.log(family); //user03 user04에 대한 객체 데이터 출력
console.log(family[0].name); //user03 = index0의 name
console.log(family[1]["name"]); // user04 = index1의 name
//->console.log(family[1].name)과 같다
감싸면 형변환이 된다
String();
Number();
const A = 1; //number type
const B = "1"; //string type
console.log(A == B); // ==동등연산자 자동적으로 형변환되어 같은 값으로 인지 1==1 true
console.log(A === B); //===일치연산자는 type까지 비교하여 number===string false
//-->js에서는 일치연산자를 사용하여 비교 진행
const C = 0;
const D = false;
const E = true;
console.log(C == D); //형 동일 true
console.log(C == E); //number===boolean false
거짓에 해당하는 것들
- 숫자0
- null
- undefined
- false
- NaN
- "빈 문자데이터"
const fruits = ["사과", "바나나", "포도", "수박"];
const emptyArr = [];
if (fruits) {
console.log("배열데이터 안에 아이템이 들어있다");
}
//값이 들어있으니 참
if (emptyArr.length) {
console.log("배열데이터 안에 아이템이 들어있다");
} else {
console.log("배열데이터 안에 아이템이 들어있지 않다");
console.log("배열의 길이(length)가 0이므로 거짓이다");
}
//emptyArr.length = 숫자 0 = 거짓
const num = 100;
console.log(typeof num); //number
console.log(typeof "Hello"); //string
console.log(typeof "Hello" === "string"); //true (string === string)
console.log(typeof false === "boolean"); // true (typeof false = bollean)
console.log(typeof undefined === "undefined"); // true (undefined의 type은 undefinded)
console.log(typeof null === "null"); // false (null값의 type은 object)
console.log(typeof null); //object
console.log(typeof []); //object
//js에서 배열은 특수한 형태의 객체. 객체(배열, 일반객체, null)는 object기반 함수로, object타입을 반환
console.log(typeof {}); //object
//constructor : 객체의 생성자 함수를 참조하는 속성
console.log([].constructor); //배열의 생성자 함수 -> [Function:Array] Array 생성자 함수 반환
console.log([].constructor === Array); //true (배열의 constructor이 array인가? true)
console.log({}.constructor === Object); //false (객체의 constructor이 object인가? false)
//ㄴ객체의 constructor 속성은 Object.prototype.constructor를 가리킨다. 이때 Object와 Object.prototype는 달라서 false
typeof연산자가 null을 객체 취급하여 object를 반환한다.
null의 타입을 확인하려면 typeof를 사용하지 않고,
Object.prototype.toString.call(null)을 사용하는 것이 더 안전하고 확실한 방법이다
console.log(Object.prototype.toString.call(null)); //[object Null]
console.log(Object.prototype.toString.call(null).slice(8, -1)); //Null (8번째 index N -1)
함수로 묶어서 코드 재사용
function checkType(data) {
//인자 data
return Object.prototype.toString.call(data).slice(8, -1);
}
console.log(checkType(null)); //checkType 함수 생성 -> null이라는 체크할 데이터 넣어줌
console.log(checkType([])); //[]에 대한 타입이 잡힘 -> Array
console.log(checkType({})); //Object 출력
console.log(checkType("안녕하세요")); //string
console.log(checkType(function () {})); //function
console.log(checkType(true)); //boolean
console.log(checkType(undefined)); //undefined
console.log(10 + 20);
console.log(20 - 10);
console.log(10 * 20);
console.log(20 / 10);
//나머지 연산자를 통해 짝/홀수 구분
console.log(20 % 3); //나머지연산자 : 나머지값을 반환. => 나머지2
//짝수를 구하는 함수
function isEven(num) {
return num % 2 === 0; //2로 나눈 값이 0이면 true 리턴
}
console.log(isEven(5)); //false
console.log(isEven(10)); //true
let a = 10;
a = a + 10;
console.log(a);
증강연산자 increment & decrement
let c = 30;
console.log(c++); //30 -> 로직실행 뒤 ++가 연산이라 그대로 30
console.log(c); //31 ->나중에 증가
let d = 30;
console.log(++d); //31 -> ++가 먼저 증가되고 로직실행되서 31
console.log(d); //31
let e = 30;
console.log(e--); //30 -> 로직 실행 뒤 --되어 그대로 30
console.log(e); //29 -> 나중에 감소
let f = 30;
console.log(--f); //29 -> --로 먼저 감소되고 로직 실행되서 29
console.log(f); //29
//for 반복문
for (let i = 0; i < 10; i++) {
// 반복문이 시작될 때 i=0으로 초기화(초기 1회) -> 매 반복시 i가 10보다 작으면 로직 실행되며, false가 되면 반복문 종료 -> i++로 반복문 실행 시 i가 1씩 증가
}
let & const
- let
변수 선언시 재할당 가능. 변수에 새로운 값을 할당 할 수 있음. 변경 가능한 값을 다룰 때 사용let a = 10; a = a + 10; // a는 10에서 20으로 재할당 console.log(a); // 20
- const
상수 선언시 사용. 상수 자체가 한 번 할당된 값을 변경 할 수 없는 변수임. 즉 const로 선언된 변수는 재할당 불가하며 값 변경할 수 없음.const a = 10; a = a + 10; // 오류 발생 -> 재할당 불가 // 배열이나 객체처럼 참조 타입의 경우 내부 값은 변경 가능 const arr = [1, 2, 3]; arr.push(4); // 배열의 내부 값은 변경 가능 console.log(arr); // [1, 2, 3, 4]
1. 함수 선언문(declaration)
function 키워드를 사용해서 함수를 생성
function fn(){}
//fn=이름
2. 함수 표현식(expression)
const fn = () => {}
const fn = function(){}
함수 호이스팅
자바스크립트에서 함수 호이스팅(function hoisting)은 함수 선언이 해당 함수의 호출보다 먼저 평가되는 개념
즉 자바스크립트의 엔진은 함수선언을 코드 실행 전에 끌어올려서 처리하기 때문에 함수가 선언되기 전에 호출해도 에러가 발생하지 않는다.
따라서 하단의 hello()함수 호출의 코드가 함수 선언 이전에 작성되어도 작동하는 것이 바로 이 이유에서이다.
단 함수 호이스팅 현상은 '함수 선언문'에서만 발생하고 함수 표현식에서는 발생하지 않는다.
hello(); //함수 호이스팅을 통한 함수 선언
fn();
//함수 선언문으로 함수를 선언했을때, 어떤 함수인지 모른 상태로 먼저 호출되어도 hello가 실행됨 = 함수 호이스팅이 발생한다
function hello() {
console.log("함수 선언문으로 작성");
return "Hello world"; //return 키워드 이후에 작성된 코드는 동작하지 않는다
}
//함수 표현식에서는 함수 호이스팅이 발생하지 않는다
const fn = function () {
console.log("함수 표현식으로 작성");
};
함수는 하나의 데이터로써, 소괄호를 열고 닫지 않으면 하나의 함수 데이터이고 소괄호를 열고 닫아야지만 함수를 실행한다
a(b); //b:콜백(콜백함수)
함수가 실행될때 인수/인자로 들어가는 또다른 함수를 콜백이라고 한다.
const c = (callback) => {
callback();
};
콜백은 함수 데이터이므로, 소괄호를 열고 닫아서 실행시킬 수 있다
undefined 나오는 경우!!!!
1. 식별자에 어떤값도 할당x
2. 객체데이터 없는값 참조
3. 함수에 return이 없을때
const sum = (a, b) => { //인자로 ab받아서
setTimeout(() => { //settimeout으로 1초 딜레이
return a + b;
}, 1000);
};
console.log(sum(1, 2)); //sum함수에 retrun이 없다(setTimeout에 return존재)->undefined
console.log(sum(3, 7));
재귀 호출은 개념적으로 함수 내부에서 자기 자신을 다시 호출한다는 것. 주의사항은 재귀호출은 무한으로 반복 실행되기때문에 멈출수있는 조건식을 반드시 작성해주어야한다.
처음 user에 userd를 넣음
그때의user.parent값은 userc니까 user.parent값 있음 함수 동작함
그럼 user값에 userc들어감
userc의 user.parent값 userb 있음 -> user값이 userb로 변경
userb의 user.parent값 usera
user이 usera로 변경 -> usera는 parent값 없어서 return user로 usera 출력함
일반함수의 this는 호출위치에서 정의
화살표 함수의 this는 자신이 선언된 함수(렉시컬)범위에서 정의
렉시컬:함수가 동작할 수 있는 유효한 범위를 의미
동기 (synchronous) : 코드가 순차적으로 실행되는것
비동기(asynchronous) : 코드가 순차적으로 실행되지 않는것
콜백패턴
코드가 점점 들여쓰기 방식으로 작성하게 되는데 이를 콜백지옥이라고 한다.
resolve : 비동기 작업이 성공적으로 완료되었을때 호출되는 함수
reject : 비동기작업이 실패했을때 호출되는 함수
const a = () => {
return new Promise((resolve)=>{
})
}
await은 뒤에있는걸 기다렸다가 호출한다는 의미
async await 로직을 쓸때 비동기 로직을 썼는데, 코드 자체는 동기로직처럼 보임.
콘솔과같은 동기 방식으로는 await을 쓸수업승ㅁ
promise 인스턴스를 반환하는 값에서만 사용~
에러핸들링
정상적으로 로직이 동작하게 되면 두번째 인수부분의 콜백이 실행되는 것이고
정상적으로 로직이 동작하지 않으면 세번째 인수부분의 콜백이 실행되는 구조
promise 인스턴스를 반환하기 때문에 then메서드를 사용할 수 있음
promise에서는 then catch finally
async awiat에서는 try catch finally를 사용
자바스크립트는 클래스라는 개념이 없다.
프로토타입은 객체를 확장
클래스는 프로토타입의 언어
프로토타입
아래코드는 getName이라는 함수를 새롭게 만든 것
정리하면 프로토타입이라는 것은 new키워드를 통해서 만든 생성자 함수에서 반환된 결과 -> ARRAY든 넘버든 ..
여기서는 fruit라는 배열데이터 혹은 인스턴스라고 일컫는다
이렇게 인스턴스에서 쓸수있는 별도의 속성이나 메서드를 등록하는 객체를 프로토타입이라고 한다
원시타입, 참조타입들도 마찬가지로 다양한 데이터들은 생성자 함수를 통해서 반환된 결과이고 우리가 그동안 생성자함수를 사용하지 않고 각각의 데이터를 만든것은 더 쉽게 만들수있게 각각의 리터럴 방식으로 만들었을 뿐이다.
= 리터럴 방식을 도입해서 배열[] 객체{} 문자"" 등.. 간단하게 쓸수있도록 반환시킨거고, 생성자함수가 내포되어있다~
그래서 string문자를 써도 내포되어있는 함수를 사용할 수 있는거임
프로토타입이라는 개념을 알아야됨!!!
생성자함수로 객체만듬. 새로운객체만드는데 firstName이라는 key값을 firstName이라는 인자로 할당하고 / lastname도 ... 해서 객체 생성
https://blog.naver.com/weartstudio/223462479317
새로운 객체가 생성되는 것 = 인스턴스화
new 키워드를 통해서 User라는 객체를 만들어 만들어 생성자함수를 만듬 ->ex) new User
객체: 객체지향 프로그래밍의 대상, 생성된 인스턴스
클래스: 객체를 프로그래밍 하기위해 코드로 정의해 놓은 상태
인스턴스: new 키워드를 사용하여 클래스를 메모리에 생성한 상태
만들어지는 과정 = 인스턴스화
getter / setter
get : 조회 / set : 새롭게 할당하는 개념