자바스크립트

 

 

인프런 수강하기 ==>   왕 초보 자바스크립트

 

 

입문자를 위해 준비한
[프로그래밍 언어] 강의입니다.

이 수업은 기초 자바스크립트 수업으로, 자바스크립트를 모르는 "완전 초보자"를 대상으로 진행합니다.

 

 

 

강의목록  :  https://www.youtube.com/playlist?list=PLZKTXPmaJk8JDicsOyY2cTcwXmBa-ZceI

 

코드펜  :  https://codepen.io/pen/

 

 

 

 

1.변수

 

 

변수명 규칙

1. 변수명의 첫 글자는 영문자, 달러($), 언더 바(_)만 올 수 있다.

2. 두번째 이후 글자는 영문자, 달러($), 언더 바(_)와 숫자만 올 수 있다.

3. 변수명의 영문자는 대문자와 소문자를 엄격하게 구분한다.

4. 자바스크립트의 예약어가 아니어야 한다.

 

변수 선언  - 자바스크립트에서 var, let, const 차이점

var 선언은 전역 범위 또는 함수 범위이며, let 및 const는 블록 범위이다.

var 변수는 범위 내에서 업데이트하고 다시 선언 할 수 있다. (재선언 O, 재할당 O)

let 변수는 업데이트 할 수 있지만 다시 선언 할 수는 없다. (재선언 X, 재할당 O)

const 변수는 업데이트하거나 다시 선언 할 수 없다. (재선언 X, 재할당 X)

 

 

 

 

 

 

2.자료형

 

 

원시 값

객체를 제외한 모든 타입은 불변 값(변경할 수 없는 값)을 정의합니다. 예를 들어 (C 언어와는 달리) 문자열은 불변합니다. 이런 일련의 타입을 "원시 값"이라고 합니다.

Boolean 타입

Boolean 타입은 논리 요소를 나타내며 true와 false 두 가지의 값을 가질 수 있습니다. 불리언과 Boolean에서 더 자세히 알아보세요.

Null 타입

Null 타입은 null 하나의 값만 가질 수 있습니다. Null과 null에서 더 자세히 알아보세요.

Undefined 타입

값을 할당하지 않은 변수는 undefined 값을 가집니다. Undefined와 undefined에서 더 자세히 알아보세요.

Number 타입

ECMAScript는 Number와 BigInt 두 가지의 내장 숫자 타입을 가지고 있습니다. (BigInt는 아래를 보세요)

Number 타입은 배정밀도 64비트 이진 형식 IEEE 754 값(-(2^53 − 1)부터 2^53 − 1까지의 수)입니다. Number 타입은 부동소수점 숫자 외에도 +Infinity, -Infinity, NaN("Not a Number") 세 개의 상징적인 값을 가집니다.

 

 

 

 

3.alert, prompt, confirm

 

 

alert

alert("Hello");

 

 

 

prompt

브라우저에서 제공하는 prompt 함수는 두 개의 인수를 받습니다.

result = prompt(title, [default]);

 

let age = prompt('나이를 입력해주세요.', 100);

alert(`당신의 나이는 ${age}살 입니다.`); // 당신의 나이는 100살입니다.

 

 

confirm

let isBoss = confirm("당신이 주인인가요?");

alert( isBoss ); //

 

 

자료형 타입 찾기  typeof  

 

 

4.형변환

 

prompt 입력 받은 값은 무조건 문자형, 취소 버튼 클릭시  null 반환  Number(null) 은  0 이 반환

 

 

"6"/"3" = 2  자동형변환

 

- 문자형을 숫자형으로 변환하기

 

var 변수 = parseInt(문자);    //문자를 정수형 숫자로 변환해줌

var 변수 = parseFloat(문자);     //문자를 실수형 숫자로 변환해줌

var 변수 = Nember(문자);    //문자를 정수&실수형 숫자로 변환해줌

 

String(3) 문자형

 

* Boolean()  불린형으로 반환 

 false 반환   => 1)숫자 0    ,  2)빈문자열''    , 3)null     ,4)undefined    ,5)NaN

나머지는 true 반환

 

Number(null) 0  되고 Number(undefined) 는   NaN 이 된다.

 

Boolean(0) ;    false

Boolean('0') ;    true

Boolean('') ;    false

Boolean('  ') ;    true

 

 

 

 

5.기본 연산자

 

증감 연산자(increment and decrement operator)

증감 연산자는 피연산자를 1씩 증가 혹은 감소시킬 때 사용하는 연산자입니다.

이 연산자는 피연산자가 단 하나뿐인 단항 연산자입니다.

 

증감 연산자는 해당 연산자가 피연산자의 어느 쪽에 위치하는가에 따라 연산의 순서 및 결과가 달라집니다.

증감 연산자설명

++x먼저 피연산자의 값을 1 증가시킨 후에 해당 연산을 진행함.

x++먼저 해당 연산을 수행하고 나서, 피연산자의 값을 1 증가시킴.

--x먼저 피연산자의 값을 1 감소시킨 후에 해당 연산을 진행함.

x--먼저 해당 연산을 수행하고 나서, 피연산자의 값을 1 감소시킴.

 

 

 

 

6.비교 연산자, 조건문(if, else)

 

1) 비교 연산자(comparison operator)

비교 연산자는 피연산자 사이의 상대적인 크기를 판단하여, 참(true)과 거짓(false)을 반환합니다.

비교 연산자는 모두 두 개의 피연산자를 가지는 이항 연산자이며, 피연산자들의 결합 방향은 왼쪽에서 오른쪽입니다.

비교 연산자설명

==왼쪽 피연산자와 오른쪽 피연산자의 값이 같으면 참을 반환함.

===왼쪽 피연산자와 오른쪽 피연산자의 값이 같고, 같은 타입이면 참을 반환함.

!=왼쪽 피연산자와 오른쪽 피연산자의 값이 같지 않으면 참을 반환함.

!==왼쪽 피연산자와 오른쪽 피연산자의 값이 같지 않거나, 타입이 다르면 참을 반환함.

>왼쪽 피연산자의 값이 오른쪽 피연산자의 값보다 크면 참을 반환함.

>=왼쪽 피연산자의 값이 오른쪽 피연산자의 값보다 크거나 같으면 참을 반환함.

<왼쪽 피연산자의 값이 오른쪽 피연산자의 값보다 작으면 참을 반환함.

<=왼쪽 피연산자의 값이 오른쪽 피연산자의 값보다 작거나 같으면 참을 반환함.

 

2) 일치 연산자

  • 동등 연산자는 ==은 0과 false를 구별하지 못한다.
alert( 0 == false ); // true

alert( '' == false ); // true

 

이유?

  • 동등 연산자 ==가 형이 다른 피연산자를 비교할 때 피연산자를 숫자형으로 바꾸기 때문에 발생
  • 즉, false는 숫자형으로 변환하면 0이기 때문에

해결 방법 :: ===, strict equality operator

  • 일치 연산자(strict equality operator) ===를 사용하면 형 변환 없이 값을 비교할 수 있다.
  • ===은 자료형의 동등 여부까지 검사한다.\
alert( 0 === false ); // false

// null과 undefined를 비교하면 특별한 규칙이 적영돼 true를 반환

alert( null == undefined ); // true

 

 

3)기본 if ... else 문법

기본 if...else 문법은 의사 코드(pseudocode)로 다음과 같이 보입니다:

if (조건) {
  만약 조건(condition)이 참일 경우 실행할 코드
} else {
  대신 실행할 다른 코드
}

 

 

 

 

7.논리 연산자(AND, OR, NOT)

 

 

 

 

 

# 단축평가 사용법

단축 평가는 ① 'null / undefiend 체크',  ② '함수 매개변수 기본값 설정', ③ '조건부 변수값 할당' 등에 사용할 수 있다.

 

1. null / undefined 체크

단축 평가를 사용하면 null, undefined과 관련된 문제를 예방할 수 있다.

const obj = null;

const myName = obj.name;  // TypeError: Cannot read property 'name' of null

null로 선언된 변수의 프로퍼티를 참조하려고 해서 타입에러가 발생하고 있다.

 

 

&& 연산자의 단축평가를 사용하면 이런 에러를 예방할 수 있다.

const obj = null;

const myName = obj && obj.name;  // 에러가 발생하지 않는다.

console.log(myName);  // null

1) obj가 null이면 false로 평가되므로, 오른쪽은 볼 것도 없이 왼쪽 값인 obj(null)이 할당된다.

2) obj가 null이 아니면 true로 평가되므로, 오른쪽의 obj.name 값을 참조한다.

이 경우엔 1번 케이스로 작동했다.

 

 

(참고) undefined의 프로퍼티를 참조할 때도 동일한 문제가 발생하며, 동일하게 해결할 수 있다.

let a;  // 초기화 없이 선언만 하면 undefined가 할당된다.

cosole.log(a.name) // TypeError: Cannot read property 'name' of undefined

console.log(a && a.name);  // undefined

 

단축평가를 활용하면 안정성 있는 코딩이 가능해진다고 볼 수 있겠다.

 

 

 

2. 함수 매개변수 기본값 설정

단축평가를 사용하면, 함수 매개변수의 기본값을 설정할 수 있다.

 

아래 코드를 보자.

function getName(name){

    const yourName = name;
    
    return yourName;
    
}


getName();  // undefined

getName() 함수 호출 시, name 파라미터에 인수를 전달하지 않았다.

이 경우, name 파라미터에는 undefined가 내부적으로 할당된다.

 

만약 함수의 리턴값인 undefined 값을 다른 곳에서 참조할 경우, 문제의 소지가 될 수 있다.

(여기서 문제가 발생한지도 모르고 헤맬 수도 있고...)

 

 

|| 연산자의 단축평가를 사용하면, 매개변수의 기본값을 설정할 수 있다.

function getName(name){

    const yourName = name || "무명";
    
    return yourName;
    
};


getName('정우성')  // "정우성"

getName();  // "무명"

1) 매개변수 name에 값이 할당된다면 true로 평가되므로, name값을 사용한다.("정우성")

2) name을 할당하지 않는 경우, name에 undefined가 할당되어 false로 평가 되므로 ||연산자 오른쪽의 "무명"을 사용한다.

 

 

마찬가지 방식으로, 아래와 같이 외부에서 받은 값을 체크할 때도 사용할 수 있다.

let response = '';  // 외부에서 받은 값이라고 가정

let myResult = response || 'default';

console.log(myResult);  // 'default'

 

 

 

 

3. 조건부 변수값 할당

if문으로 변수에 값을 할당하는 코드를 단축평가로 대체할 수 있다.

 

<if문으로 변수값 할당>

let condition = true;
let result = '';

if (condition) result = '참';

console.log(result);  // '참'

 

 

<단축평가로 변수값 할당>

let condition = true;
let result = '';

result = condition && '참';  // if문 대신, 단축평가 사용

console.log(result);  // '참'

condition 값이 true이면, 오른쪽의 '참'이 반환되어 할당된다.

condition 값이 false이면, 왼쪽(false) 값이 그대로 반환되어 false가 할당된다.

출처: https://curryyou.tistory.com/193 [카레유:티스토리]

 

 

 

 

8.반복문(for, while, do while)

 

 

 

1. for 문: 고전적인 for문

=> for(let i = 0; i < 10; i++){...반복 수행 코드...}

for (let i = 0; i < 10; i++){
    console.log(i); // 0~9까지 출력
}

* (주의) 변수 선언 시, const를 쓰면 값 변경이 불가하여 에러가 발생하니 주의

 

 

2. for in 문: 객체의 프로퍼티 키 열거 전용

=> for(const key in 객체){...반복 수행 코드...}

* (주의)해당 객체가 상속받는 프로토타입 체인상의 모든 프로퍼티 키를 열거한다.(단, [[Enumerable]] 값이 false인 프로퍼티는 제외)

const obj = {
    name: 'curryyou',
    job: 'engineer'
}

for (const key in obj){
    console.log(`${key} : ${obj[key]}`);
}
// name : curryyou
// job : engineer

 

 

3. for of 문: 이터러블 순회 전용

=> for(const item of 이터러블){...반복 수행 코드...}

const arr = [10, 20, 30];
for (const item of arr){
    console.log(item); // 10, 20, 30 출력
}

* (참고) 이터러블에는 String, Array, Map, Set, DOM컬렉션(HTMLColletion, NodeList) 등이 있다.

 

 

4. forEach(): 배열 순회 전용 메서드

=> 배열.forEach( function(value, index, array){...반복 수행 코드...} )

* 콜백함수의 매개변수로 value에 요소값, index에 인덱스, array에 원본 배열이 들어온다.

[10, 20, 30].forEach((value, index, array)=>{
    console.log(`${index} : ${value}`); // 0 : 10, 1 : 20, 2: 30 출력
})

 

 

5. while 문: 고전적인 while문

=> while(조건식){...반복 수행 코드...}

let num = 0;
while(num <3){ 
    console.log(num);  // 0~2 까지 출력
    num++;
}

 

 

6. do while 문: 고전적인 do...while문

=> do{...반복 수행 코드...} while(조건식);

do{
    console.log('일단 한번은 실행된다.'); // 이 코드만 한번 실행되고 반복 종료.
}while(false);

 

 

 

7. Array.prototye 메서드 : 배열 전용

1) 배열.forEach( (value, index, array)=>{...반복 수행 코드...} )

: 배열의 length만큼 반복하여 콜백함수를 호출한다.

: 콜백함수의 매개변수로 value에 요소값, index에 인덱스, array에 원본배열이 들어온다.

[1, 2, 3, 4].forEach((value, index, array)=>{
    console.log(value);  // 1, 2, 3, 4 출력
})

 

2) 배열.map( (value, index, array)=>{...반복 수행 코드...} )

: forEach와 동일(순회 방식, 콜백함수 매개변수 등)

: 다른점 => 각 콜백함수에서 return 하는 값들으로 새로운 배열을 만들어 반환한다.

const map_reuslt = [1, 2, 3, 4].map((value, index, array)=>{
    console.log(value); // 1, 2, 3, 4 출력
    return value*10; // 각 요소에 10을 곱한 값을 배열로 반환
})

console.log(map_reuslt);  
// [ 10, 20, 30, 40 ]

 

3) 배열.filter( (value, index, array)=>{...반복 수행 코드...} )

: forEach와 동일(순회 방식, 콜백함수 매개변수 등)

: 다른점 => 각 콜백함수에서 return하는 값이 true일 때만, 그때의 value 값들로 새로운 배열을 만들어 반환한다.

const filter_result = [1, 2, 3, 4].filter((value, index, array)=>{
    console.log(value); // 1, 2, 3, 4 출력
    return value%2 == 0; // value가 짝수인 값들을 배열로 반환
})

console.log(filter_result); 
// [ 2, 4 ]

 

4) 배열.reduce( (previousValue, currentValue, currendIndex, array)=>{...반복 수행 코드...}, initialValue )

: 두번째 매개변수인 initialValue값을 시작으로,

: 각 콜백함수가 return하는 값이 다음에 실행되는 콜백함수의 previousValue로 들어간다.

: 최종적으로 마지막 콜백함수가 return하는 값을 반환한다.(아래의 코드를 보면 이해가 잘 됨.)

const reduce_result = [1, 2, 3, 4].reduce((pv, cv, idx, arr)=>{
    return pv + cv; // 이전 콜백함수가 리턴한 값에 현재의 요소 값을 더함(누적 개념)
}, 100); // 100을 초기값으로 줌

console.log(reduce_result); 
// 110 (100 + 1 + 2 + 3 + 4 결과)

* 배열에는 이 외에도 every(), some(), find(), findIndex() 등의 메서드가 존재한다.

 

출처: https://curryyou.tistory.com/202 [카레유:티스토리]

 

 

 

 

9.switch문

 

if…else 문의 조건식이 반드시 불리언 값으로 평가되는 반면,
switch 문의 표현식은 불리언 값보다는 문자열, 숫자 값인 경우가 많다.
if…else 문은 논리적 참, 거짓으로 실행할 코드 블록을 결정한다.
하지만 switch 문은 논리적 참, 거짓보다는 다양한 상황(case)에 따라 실행할 코드 블록을 결정할 때 사용한다.

 

function switchOfStuff(val) {
  var answer = "";
  switch (val){
    case "a":
      answer = "apple";
      break;
    case "b":
      answer ="bird";
      break;
    case "c":
      answer ="cat";
      break;
    default:
      answer ="해당 데이터는 없습니다."; 
      break;
  }
  return answer;
}

switchOfStuff(1)       //"stuff"  
switchOfStuff("c")     //"cat"

 

 

 

 

 

 

10.함수(function)의 기초

 

함수의 정의

자바스크립트에서 함수의 정의는 function 키워드로 시작되며, 다음과 같은 구성요소를 가집니다.

 

1. 함수의 이름

2. 괄호 안에 쉼표(,)로 구분되는 함수의 매개변수(parameter)

3. 중괄호({})로 둘러싸인 자바스크립트 실행문

 

자바스크립트에서 함수를 정의하는 문법은 다음과 같습니다.

문법

function 함수이름(매개변수1, 매개변수2,...) {

    함수가 호출되었을 때 실행하고자 하는 실행문;

}

함수 이름(function name)은 함수를 구분하는 식별자(identifier)입니다.

매개변수(parameter)란 함수를 호출할 때 인수(argument)로 전달된 값을 함수 내부에서 사용할 수 있게 해주는 변수입니다.

 

예제

// addNum라는 이름의 함수를 정의함.

function addNum(x, y) {    // x, y는 이 함수의 매개변수임.

    document.write(x + y);

}

addNum(2, 3);              // addNum() 함수에 인수로 2와 3을 전달하여 호출함.

 

출처:  http://www.tcpschool.com/javascript/js_function_basic

 

 

매개변수 name="friend"    name 값이 이 없으면 friend 값 입력

function sayHello(name="friend"){
  let msg =`Hello, ${name}`;
  console.log(msg);
}

sayHello();
sayHello('Jane');

출력 :

"Hello, friend"
"Hello, Jane"

 

리턴문의 없는 함수 및 반환값이 없는 함수는 항상  undefined 값 반환

function shoError(){
  alert("에러가 발생했습니다.");
  return;
  alert('이 코드는 절대 실행되지 않습니다.');
}

const result =shoError();
console.log(result);

 

- 함수 (function)

1 .한번에 한작업에 집중

2. 읽기 쉽고 어떤 동작인지 알 수 있게 네이밍

3 . 동사  + 무엇

1)showError

2)getName

3)createUserData

 

 

 

 

 

 

11.함수 표현식, 화살표 함수(arrow function)

 

 

 

함수 표현식 vs 함수 선언식

 

일반적인 프로그래밍 언어에서의 함수 선언과 비슷한 형식이다.

function 함수명() {
  구현 로직
}

 

// 예시
function funcDeclarations() {
  return 'A function declaration';
}
funcDeclarations(); // 'A function declaration'

 

함수 표현식 - Function Expressions

유연한 자바스크립트 언어의 특징을 활용한 선언 방식

var 함수명 = function () {
  구현 로직
};

 

// 예시
var funcExpression = function () {
    return 'A function expression';
}
funcExpression(); // 'A function expression'

 

함수 선언식과 표현식의 차이점

함수 선언식은 호이스팅에 영향을 받지만, 함수 표현식은 호이스팅에 영향을 받지 않는다.

함수 선언식은 코드를 구현한 위치와 관계없이 자바스크립트의 특징인 호이스팅에 따라 브라우저가 자바스크립트를 해석할 때 맨 위로 끌어 올려진다.

예를 들어, 아래의 코드를 실행할 때

// 실행 전
logMessage();
sumNumbers();

function logMessage() {
  return 'worked';
}

var sumNumbers = function () {
  return 10 + 20;
};

 

호이스팅에 의해 자바스크립트 해석기는 코드를 아래와 같이 인식한다.

// 실행 시
function logMessage() {
  return 'worked';
}

var sumNumbers;

logMessage(); // 'worked'
sumNumbers(); // Uncaught TypeError: sumNumbers is not a function

sumNumbers = function () {
  return 10 + 20;
};

 

위 코드 결과는 아래와 같다.

오류메시지

함수 표현식 sumNumbers 에서 var 도 호이스팅이 적용되어 위치가 상단으로 끌어올려졌다.

var sumNumbers;

logMessage();
sumNumbers();

 

하지만 실제 sumNumbers 에 할당될 function 로직은 호출된 이후에 선언되므로, sumNumbers 는 함수로 인식하지 않고 변수로 인식한다.

 

 출처  : > 2022 캡틴판교 powered by Jekyll

 

 

1. 화살표 함수의 선언

화살표 함수(Arrow function)는 function 키워드 대신 화살표(=>)를 사용하여 보다 간략한 방법으로 함수를 선언할 수 있다. 하지만 모든 경우 화살표 함수를 사용할 수 있는 것은 아니다. 화살표 함수의 기본 문법은 아래와 같다.

// 매개변수 지정 방법
    () => { ... } // 매개변수가 없을 경우
     x => { ... } // 매개변수가 한 개인 경우, 소괄호를 생략할 수 있다.
(x, y) => { ... } // 매개변수가 여러 개인 경우, 소괄호를 생략할 수 없다.

// 함수 몸체 지정 방법
x => { return x * x }  // single line block
x => x * x             // 함수 몸체가 한줄의 구문이라면 중괄호를 생략할 수 있으며 암묵적으로 return된다. 위 표현과 동일하다.

() => { return { a: 1 }; }
() => ({ a: 1 })  // 위 표현과 동일하다. 객체 반환시 소괄호를 사용한다.

() => {           // multi line block.
  const x = 10;
  return x * x;
};

 

 

#2. 화살표 함수의 호출

화살표 함수는 익명 함수로만 사용할 수 있다. 따라서 화살표 함수를 호출하기 위해서는 함수 표현식을 사용한다.

// ES5
var pow = function (x) { return x * x; };
console.log(pow(10)); // 100
// ES6
const pow = x => x * x;
console.log(pow(10)); // 100

또는 콜백 함수로 사용할 수 있다. 이 경우 일반적인 함수 표현식보다 표현이 간결하다.

// ES5
var arr = [1, 2, 3];
var pow = arr.map(function (x) { // x는 요소값
  return x * x;
});

console.log(pow); // [ 1, 4, 9 ]
// ES6
const arr = [1, 2, 3];
const pow = arr.map(x => x * x);

console.log(pow); // [ 1, 4, 9 ]

 

출처 : https://poiemaweb.com/es6-arrow-function

 

 

 

 

 

12.객체(Object)

 

예1

const superman = {
    name: 'clark',
    age: 33,
}

//#접근
console.log("접근 : superman.name:",superman.name);
            
//추가
superman.gender = 'male';
superman['hairColor'] = 'black';
console.log("추가  : " ,superman);

delete superman.hairColor;
console.log("삭제 : " ,superman);

출력

"접근 : superman.name:" "clark"
"추가  : " // [object Object] 
{
  "name": "clark",
  "age": 33,
  "gender": "male",
  "hairColor": "black"
}
"삭제 : " // [object Object] 
{
  "name": "clark",
  "age": 33,
  "gender": "male"
}

 

 

예2

 

function isAdult(user) {
    console.log("'age' in user :", ('age' in user));
    console.log("user.age : ", user.age);
    if (('age' in user) ||
        user.age < 20) {
        return false;
    }
    return true;
}

const Mike = {
    name: "Mike",
    age: 30
}

const Jane = {
    name: "Jnne"
}

console.log("isAdult(Mike)", isAdult(Mike));
console.log("isAdult(Jane)", isAdult(Jane));

 

출력

"'age' in user :" true
"user.age : " 30
"isAdult(Mike)" false



"'age' in user :" false
"user.age : " undefined
"isAdult(Jane)" true

 

 

예3)

const Mike = {
    name: "Mike",
    age: 30
}

for(key in Mike){
  console.log( " key  : " , Mike[key]);
}

 

출력

" key  : " "Mike"
" key  : " 30

 

 

 

 

 

 

13.객체(Object) - method, this

 

 

 

화살표 함수는 일반 함수와는 달리 자신만의 this 를 가지지 않음.


화살표 함수 내부에서 this 를 사용하면, 그 this는 외부에서 값을 가져옴

 

let boy = {
    name: "Mike",
    showName:function(){      
      console.log(this.name);
    }
}

let man=boy;
//man.name="Tom";
boy=null;

man.showName();

 

"Mike"

 

 

 

 

 

14.배열(Array)

 

 

 

객체는  for in    배열은 for of  사용 ; 

 

let days =["man",  "true", "wed"];


console.log(days[1]);

days[2]="수요일";

//배열 맨 뒤에 thu 추가
days.push("thu");

//배열 맨 앞에 sun 추가
days.unshift("sun");

console.log(days);

for(let i=0; i<days.length; i++){
  console.log("for index : ", days[i]);
}

for(let i of days){
  console.log("for of 문 :" ,i);
}




 

 

"true"
// [object Array] (5)
["sun","man","true","수요일","thu"]
"for index : " "sun"
"for index : " "man"
"for index : " "true"
"for index : " "수요일"
"for index : " "thu"
"for of 문 :" "sun"
"for of 문 :" "man"
"for of 문 :" "true"
"for of 문 :" "수요일"
"for of 문 :" "thu"

 

 

 

15.마치며

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

about author

PHRASE

Level 60  라이트

What is learned in the cradle is carried to the grave. (요람에서 배운 것 무덤까지)

댓글 ( 4)

댓글 남기기

작성