[JAVASCRIPT] 이론 2

prototype 프로퍼티

모든 함수는 객체로서 prototype 프로퍼티를 가지고 있다.
prototype 프로퍼티는 함수가 생성될 때 만들어지며 constructor 프로퍼티 하나만 있는 객체를 가리킨다.
constructor 프로퍼티는 prototype 프로퍼티를 참조하며 서로 참조하는 관계를 가진다.

함수의 다양한 형태

자바스크립트에서 함수 표현식에서 함수이름은 필수 사항이 아니다.
함수이름을 붙이지 않은 것을 익명함수라고 하고 대표적으로 콜백함수가 있다.

콜백함수

콜백 함수란 코드를 통해 명시적으로 호출되는 함수가 아닌 어떤 이벤트나 특정 시점에 도달했을때 시스템에서 호출되는 함수를 말한다.
이벤트 발생 -> 이벤트 핸들러가 함수 호출 -> 콜백함수 (개발자가 등록)
window.onload 이벤트 핸들러가 load 이벤트가 발생하면 콜백함수를 통해 메시지를 띄운다.

window.onload = function() {
    alert('Callback Fuction');
};

즉시 실행 함수

함수를 동의함과 동시에 바로 실행하는 함수를 즉시 실행 함수 라고 한다.
즉시 실행 함수는 같은 함수를 다시 호출 할 수 없다.
함수 리터럴을 () 감싸고 뒤에 매개변수를 바로 넘겨줌으로서 최초 한번의 실행을 필요로 하는 초기화코드에 사용할 수 있다.

(function (name) {
    console.log('This is immediate function ' + name);
})('hoyoung'); // This is immediate function hoyoung

내부 함수

자바스크립트에서는 함수 코드 내부에서도 다시 함수 정의가 가능하며 함수 내부에서 정의된 함수를 내부 함수라고 한다.

function parent() {
    var a = 10;
    var b = 20;

    function child() {
        b = 30;
        console.log(a, b);
    }

    child();
};
parent(); // 10, 30
//child(); // child is not defined

내부 함수에서는 부모함수의 변수에 접근이 가능하다.
내부 함수는 부모함수 내부에서만 호출이 가능하다.

function parent1() {
    var a = 100;
    var child = function () {
        console.log(a);
    }
    return child;
}

var inner = parent1(); // inner 변수는 child 를 가리키게 된다.
inner(); // 이와같은 함수를  `closer` 라고 한다.

// ### 함수를 리턴하는 함수
var self = function() {
    console.log('hello');
    return function () {
        console.log('world');
    }
}

self = self(); // hello
self(); // world
// self 변수에 hello 가 출력되고 리턴된 함수가 들어가게 된다.

함수 호출

arguments 객체

인자의 갯수를 넘기더라도 에러가 발생하지 않고 무시한다.


function func(arg1, arg2) {
    console.log(arg1, arg2);
};

func(); // undefined undefined
func(1); // 1 undefined
func(1,2); // 1 2
func(1,2,3); // 1 2

arguments 객체는 함수 호출 시 넘긴 인자들이 배열행태로 저장되어 n 개의 매개변수를 입력하면 length 프로퍼티의 value 는 n 이 된다.
length 프로퍼티 : 호출할 때 넘겨진 인자의 갯수
callee 프로퍼티 : 현재 실행중인 함수의 참조값

function sum () {
    var sum = 0;

    for (var i = 0; i < arguments.length; i++) {
        sum += arguments[i];
    }

    return sum;
}

console.log(sum(1,2,3,4,5)); // 15
console.log(sum(3,4,5)); // 12

arguments 객체는 매개변수 갯수가 정확하게 정해지지 않는 함수를 구현하는데 용이하다.

this 바인딩

자바 스크립트에서 함수 호출 시 arguments 객체와 this 인자가 암묵적으로 전달된다.
this 키워드는 전역객체에 바인딩 된다.
브라우저에서 자바스크립트를 실행할 경우 window 객체가 전역 객체에 해당한다.

var Obj1 = {
    name : 'Jung',
    hobby : function() {
        console.log(this.name + '\'s hobby is None');
    }
};

var obj2 = {
    name : 'Han'
};

Obj1.hobby(); // Jung's hobby is None
obj2.hobby = Obj1.hobby;
obj2.hobby(); // Han's hobby is None

// `this` 키워드는 전역객체에 바인딩 된다. 
// 브라우저에서 자바스크립트를 실행할 경우 window 객체가 전역 객체에 해당한다.

var value = 100;

var inner_ = {
    value : 1,

    func1 : function() {
        this.value ++;
        console.log('func1 called value is ' + this.value);

        func2 = function() {
            this.value ++;
            console.log('func2 called value is ' + this.value);

            fucn3 = function() {
                this.value ++;
                console.log('func3 called, value is ' + this.value);
            }

            fucn3();
        }
        func2();
    }
};

inner_.func1();
// func1 called value is 2
// func2 called value is 101
// func3 called, value is 102
// func2 부터는 this의 전역객체가 window가 되기에 value == 100이 인식된다.

객체 생성 두가지 방법

객체 리터럴 방식

var obj = {
    name : 'obj',
    text : 'my object'
};

생성자 함수

new 를 붙여 호출

function Text(name, text) {
    this.name = name;
    this.text = text;
}

두 방식의 차이점은 객체 리터럴 방식의 prototype은 Object이고 생성자함수의 prototype 은 생성자함수 이름이 된다.

var tempText = new Text('objtext', 'text');

생성자 함수에 new 없이 호출 하는경우

var tempText2 = Text('objtext2', 'text');
console.dir(tempText2); // undefined
console.log(window.name); // objtext2

this 는 함수 호출이므로 전역 객체인 window에 바인딩 되어 window 객체에 동적으로 name, text 프로퍼티가 생성된다.

apply(), call() 메서드

var temp = {};
Text.apply(temp, ['hoyoung', 'hoyoung\'s text']);
console.dir(temp); // temp 객체에 프로퍼티 생성
var temp2 = {};
Text.call(temp2, 'ho', 'ho\'s text');
console.dir(temp2);

함수나 메서드의 리턴값이 없는 경우 undefined 가 리턴된다.
생성자 함수의 리턴값이 객체가 아닌 문자, 숫자, 불린 타입이라면 무시된다.

function Person(name, age) {
    this.name = name;
    this.age = age;

    return 100;
}

var human = new Person('hoyoung', 30);
console.log(human); // 100이 리턴되지 않는다.

프로토타입 체이닝

자바스크립트의 객체는 자기 자신의 프로퍼티 뿐 아니라 부모 객체의 프로퍼티또한 접근 가능하다 -> 프로토타입 체이닝
부모 역할을 하는 프로토타입 객체의 프로퍼티를 차례대로 검색하는 것을 프로토타입 체이닝이라고 한다.

객체 리터럴 방식의 프로토타입 체이닝

var myObj = {
    name : 'hoyoung',
    sayName : function () {
        console.log(this.name + " is my name");
    }
}

myObj.sayName();
console.log(myObj.hasOwnProperty('name')); // true
console.log(myObj.hasOwnProperty('nickname')); // false
//myObj.sayNickname();

hasOwnProperty() 메서드는 Object.prototype 객체의 내장되어 있는 메소드이다.

생서자함수로 생성된 객체의 프로토타입 체이닝

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

var hoyoung = new Person('hoyoung', '24');
console.log(hoyoung.hasOwnProperty('name'));

이경우 생성자함수타입의 Person.prototype 객체는 hasOwnProperty() 메소드를 가지고 있지 않지만 Object.prototype 객체를 참조하고 있다.
Object.prototype 객체는 프로토타입 체이닝의 종점이다.

기본 타입에 메서드를 추가하여 사용할 수 있다. -> API
Number 타입에 메서드 추가

Number.prototype.test = function() {
    console.log('this is test');
};

var tempNum = 10;
tempNum.test(); // this is test

'📦 개발 > JavaScript' 카테고리의 다른 글

[JAVASCRIPT] var, let, const 비교  (0) 2023.02.02
[JAVASCRIPT] addEventListener()  (0) 2023.01.14
[JAVASCRIPT] onload()  (0) 2023.01.11
[JAVASCRIPT] 이론 1  (0) 2023.01.03
[JAVASCRIPT] 숫자 맞히기 게임  (0) 2022.12.31