[JavaScript] 4. 자바스크립트 Function, Object

keymu·2024년 10월 20일
0

1. 함수

/*
*  ▶ 함수 (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);

// ----------------------------------------------------
// 리턴값 갖는 함수 정의
//  입력: 두개의 수를 입력 받아서 
//  수행: 덧셈을 수행한뒤
//  리턴: 덧셈 결과를 리턴

2. Object

/*
    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;
    }

}

profile
Junior Backend Developer

0개의 댓글