/*
* ▶ 함수 (function)
* 자주 반복되어 수행할 코드 덩어리(?) 들을
* 1. 함수(function)로 '정의' 하고
* 2. 필요할때마다 정의된 함수를 '호출'하여 사용한다.
*
* ▶ 함수 정의 (function definition)
*
* [함수정의형식]
* function 함수이름(매개변수들..)
* {
* 함수본체 (수행 코드들...)
* }
*
*
* ▶ 함수 호출 (function call, function invocation)
* [함수호출형식]
* 함수이름(매개변수들..);
*
* - A() 함수실행중 B() 함수를 호출(call)하게 되면
* 호출한 함수 A()은 잠시 멈추고 (--> 호출한함수: caller 라고도 함)
* 호출된 함수 B()의 실행을 시작합니다 (--> 피호출함수: callee 라고도 함)
* B()의 실행이 끝나면 호출한 함수 A()로 실행이 돌아옵니다.
* 이를 '리턴 return' 한다 합니다 ↓
*
* ▶ return (리턴, 반환)
* 함수가 호출되어 함수내 코드실행이 끝나면, 호출한쪽으로 실행이 돌아옵니다.
* return 키워드를 사용하여 명시적으로 리턴할수도 있습니다. (함수는 바로 종료됩니다)
* return 키워드가 없어도, 함수실행 끝나면 자동으로 리턴합니다.
*
* return 시 어떤 값을 호출한쪽(caller) 에 돌려줄수 있다.
* return 값:
*
* ▶ 함수 매개변수(parameter), 함수 인자(argument)
* 매개변수는 함수 정의할때 명시하는 변수 (그 함수의 지역변수로서 동작한다)
* 인자 는 함수 호출할때 입력하여 매개변수에 전달하는 값
* 함수 호출시 호출인자가 매개변수에 '복사' 되어 호출한 함수 수행된다.
* ※ 두 용어는 혼용되어 사용되곤 한다.
*/
// 함수를 사용해야 하는 이유
// TODO
/*
* 프로그래밍에서 동일한(혹은 거의 비슷한) 내용의 코드가 반복될때가 있다.
* 바로 이러한 코드 낭비를 없애기 위해
* 반복되는 코드를 묶어서 하나의 함수로 정의해 놓고 사용하는 것이다
*
* 즉, 반복되는 부분이 있을 경우 "반복적으로 사용되기에 재사용할만한 가치가 있는 부분"을
* 한 코드 덩어리로 묶어서
* 1. 어떤 입력값을 주었을 때, (매개변수)
* 2. 어떠한 일을 수행하고, (본체)
* 3. 어떤 결과값을 돌려준다" (리턴값) 라는식의
* 함수로 작성하는 것이 일반이다.
*/
function sayAnthem(){
console.log("동해물과 백두산이");
console.log("마르고 닳도록");
console.log("하느님이 보우하사");
console.log("우리나라 만세");
}
sayAnthem(); // 호출
sayAnthem();
sayAnthem();
console.log(typeof sayAnthem);
console.log(sayAnthem);
console.log(sayAnthem.toString());
function sayName(name){
console.log('안녕하세요')
console.log(`제 이름은 ${name} 입니다`);
}
sayName('정문선');
sayName('절미');
// JS 에선 매개변수가 정의된 함수를 호출할때 인자 값을 지정하지 않으면, undefined 값이 전달된다!
sayName();
// JS 에선 함수정의시 지정된 매개변수보다 더 많은 인자값으로 호출하여도 에러 발생하지 않는다!
sayName('정문선', '절미');
/*********************************************
* 함수 호출 관련 디버깅 명령
* step into : 실행할 함수 내부로 이동
* step out : 실행중인 함수 리턴까지 진행
* 호출스택 (call stack) : 함수 호출관계 모니터링
*/
/* ********************************************
* return [값]
* -- 함수 종료
* -- 호출한 쪽으로 '값 하나' 을 돌려준다
*/
console.log('-'.repeat(20));
console.log('[return]');
function fullStack1(a, b){
return a + b;
}
console.log(fullStack1(10, 20));
function fullStack2(){
return; // 리턴값 명시 안되면 undefined 리턴함
console.log('데헷');
}
console.log(fullStack2());
function fullStack3(){}
console.log(fullStack3());
function codeEveryDay(){
console.log("매일 코딩중");
}
codeEveryDay();
function codeEveryDay(){ // 재정의
console.log("내일은 토요일");
}
codeEveryDay();
// 주의! 동일이름의 함수 정의하면 이전 함수정의는 사라짐
// 문제는 이전에 호출한 코드도 나중에 정의한 함수로 적용됨. (hoisting) 발생
// ----------------------------------------------------
// JS 에선 함수도 '데이터'다
// 일반적으로 JS 에선 함수를 아래와 같이 정의하는 것을 선호한다
// 상수 = function() 객체(이름없는 함수객체)
const sayHello2 = function(name, age){
console.log('-'.repeat(20));
sayName(name);
console.log(`나이는 ${age}살 입니다`);
console.log('-'.repeat(20));
};
sayHello2('신창영', 23);
console.log(typeof sayHello2);
const sayHello3 = sayHello2;
sayHello3('이동희', 26);
(function(){
console.log('데헤헤헤헤헤헤헤');
})(); // 이름없는 함수객체 생성직후 바로 호출.
(function(a, b){
console.log(`${a} + ${b} = ${a + b}`);
})(10, 13);
// ----------------------------------------------------
// 리턴값 갖는 함수 정의
// 입력: 두개의 수를 입력 받아서
// 수행: 덧셈을 수행한뒤
// 리턴: 덧셈 결과를 리턴
/*
object
property : value 쌍으로 구성된 데이터
{property:value, property:value, ...}
property 는 중복될수 없다.
value 는 어떠한 타입도 될수 있다.
: number, string, array, function, object..
사실 JavaScript 의 모든 데이터의 실체는 object 이다.
※일반적으로 object 변수는 는 const 로 선언한다
그러나 이번단원에서 진도 편의상 let 등을 사용하기도 하겠습니다
*/
let obj1, obj2, obj3, result;
const car = {type: "Fiat", model: "500", color: "white"};
/* object 의 property 사용하기
방법1 : objectName.propertyName
방법2 : objectName["propertyName"]
*/
const person = {
firstName: "John",
lastName: "Doe",
age: 50,
eyeColor: "blue",
};
console.log(person.firstName);
console.log(person['firstName']);
let a = 'firstName';
let b = 'age';
console.log(`${person[a]} 는 ${person[b]} 살입니다`);
// property 값 변경
console.log('변경전', person);
person.firstName = '제인';
console.log('변경후', person);
// person 을 const 로 선언 했는데 property 변경 가능?
// person 을 바꾸지 못한다는 거지 person 의 property 를 변경 못한다는 게 아니다
// person = {name: 'hello'}; // 요게 에러다
// property 값 추가하기
person.email = 'Jane@mail.com'; // 없던 property 추가
console.log('추가후', person);
// property 삭제. delete 연산자
delete (person.email);
console.log('삭제후', person);
// property name은 중복될수 없다
obj1 = {
score: 100,
score: 200,
'score': 300, // property 를 문자열로 표기해도 ok
Score: 400, // property name 은 대소문자 구분
};
console.log(obj1);
// property name 으로 가능한 것들은?
obj2 = {
name: 'John',
'name': 'Susan', // string
100: '점수', // number 가능
3.14: '가능',
true: '쌉가능', // boolean 가능.
undefined: '엥?', // undefined 가능?
// [10, 20, 30]: '으잉', // 배열이나 object 는 property name 으로 불가
};
console.log(obj2);
console.log(obj2[100], obj2['100']);
console.log(obj2[true], obj2['true']);
console.log(obj2[undefined], obj2['undefined']);
/* value 는 어떠한 타입도 가능하다
*/
obj2 = {
name: 'John', // string
age: 34, // number
height: 172.3, // number
married: false, // boolean
score: [100, 97, 33], // 배열
family: { // object
spouser: 'Jane', // string
children: ['Clark', 'Steve', 'Scott'], // 배열
},
};
console.log(obj2);
console.log(obj2.name);
console.log(obj2.score);
console.log(obj2.score[1]);
console.log(obj2.family.children[1]);
console.log(obj2['family'].children[1]);
console.log(obj2['family']['children'][1]);
/****************************************************
* object method 와 this
* object 의 value 는 어떠한 타입도 가능하다
* 즉, 함수도 object 의 property value 로 가능하다
* object 의 property 함수를 메소드(method) 라 부른다.
* object 안에서 this 는 '자기자신객체', 즉, 해당 object 가 참조(혹은 바인딩) 된 객체를 말한다
*/
obj3 = {
firstName: "Jane",
lastName: "Doe",
id: 5566,
// 같은 object 내의 property 사용하려면 this 꼭!
fullName: function(){
// return "Hello";
return `${this.id}] ${this.firstName} ${this.lastName}`;
},
}
console.log(obj3.fullName());
obj4 = {
firstName: "Steve",
lastName: "Jobs",
id: 9999,
};
obj4.myName = obj3.fullName;
console.log(obj4.myName());
/**
* this 의 정체!
* JS code 를 소유한(own) object다! 즉 this 는 '특정 object' 를 '참조' 한다.
* '어떤 object 를 참조하나?' → this 가 사용(호출) 되는 시점마다 '다르다'.
* (JS 의 this 가 다른 언어의 this에 비해 직관적으로 이해하기 어려운면이 있습니다)
*
* 가령
* - 'object method' 내의 this 는 함수를 소유한(own) object 참조
* - function 내의 this 는 global object 참조
* - strict mode 에서 function 내의 this 는 undefined
* - this 단독인 경우 global object 참조
* - event 에선 this 는 event 가 발생한 element 객체
* - '생성자(constructor) 안'에서의 this 는 그 자체가 값을 갖고 있진 않다.
* 단지, 생성된 새로운 object에서 치환된다.
* 즉 new 로 생성된 새로운 object 가 바로 this 가 된다.
* - call(), apply(), bind() 와 같은 메소드에선 this 는 어떠한 object 를 참조하게 할수 있다.
*
* this 는 변수가 아니다!! 키워드다!! 따라서 this 의 값을 수정할수 없다
*/
let x = {
name: "kim",
age: 34,
height: 172.3,
score: [94, 35, 79],
getTotal: function () {
let sum = this.score[0] + this.score[1] + this.score[2];
return sum;
},
getAvg: function () {
return this.getTotal() / this.score.length;
}
}