본문 바로가기

복습/Javascript

[Javascript] 객체지향 자바스크립트 [객체 part 1]

# 배열에서 객체로


* 배열은 값의 목록일 뿐이다


var myarr = ['red', 'blue', 'yellow'];
// 키(index) = 0, 1, 2
// 값 = red, blue, yellow

* 키와 값이 쌍의 테이블이다


var hero = {
    name : 'heecheol',
    job : 'ninja'
};
      
      /*
      객체를 참조하는 변수의 이름은 hero
      배열은 [], 객체는 {} 사용

        []로 배열을 정의하는것 - 배열 리터럴 표기법(array literal notation)
        {}로 객체를 정의하는것 - 객체 리터럴 표기법(object literal notation)

      요소(property)는 쉼표( , )로 구분
      key : value 와 같이 콜론으로 키와 값을 나눈다
      key의 이름이 변수로 유효한 이름이 아니면 큰따옴표나 작은따옴표로 묶는다

      var hero = {'var' : value}  => 예약어임
      var hero = {'2abc' : value} => 숫자로시작
      var hero = {"##2!" : value} => 특수문자
      */


* 배열에 요소(element)가 들어있다

* 객체에 속성(property)가 들어있다

* 함수를 가리키는 속성을 메서드(method)라고 한다


var dog = {
    name: 'choco',
    talk: function(){
        alert('wal, wal!');
    },
    action: function(what){
        return what;
    }
}
// talk는 메서드


* 객체의 접근방법
       
            대괄호 표기법

예) dog['name']

    도트 표기법
                예) dog.name

    두가지방법을 혼용해서 써도 상관없다
    대괄호 표기법이 필요한 경우는 유효한변수이름이 아니거나, 속성의 이름을 미리 알수 없을 때이다


* 객체의 접근방법

            메서드도 함수의 속성중 하나이므로 접근방법이 동일
            메서드 이름뒤에 괄호를 추가해서 실행, 인수가 있을시 함수처럼 사용


dog.say();
dog['say']();
dog.action("run"); // action에 "run" 전달


* 속성 / 메서드 변경


//
var hero = {}; // 빈 객체 생성
typeof hero.name; // "undefined"

hero.name = 'heecheol';
hero.age = 24;
hero.action = function(what){
    return what;
} // 속성과 메서드 추가

console.log(hero.name); // "heecheol"
console.log(hero.age); // 24
console.log(hero.action("run")); // "run"

delete hero.name; //속성 삭제
console.log(hero.name); // undefined


* this

        this 의 뜻은 이 객체, 현재 객체를 가리킨다


var dog = {
    name: 'choco',
    myname: function(){
        return this.name;
    }
}
// 여기서 this.name은 dog객체의 name이다



# 해시(hash)와 연관배열(associate array)


* 일반배열(regular array), 인덱스 배열 또는 열거배열로도 불림 (키는 숫자)

* 연관배열(associate array), 해시(hash) 또는 딕셔너리(dictionary)로도 불림 (키는 문자열))


# 생성자함수


* 생성자(constructor) 함수를 통해 객체를 생성하는 방법이 있다

* new 연산자를 사용하여 생성한다

* 생성자함수는 첫글자를 대문자로 하는것이 관례이다

* new 연산자를 사용하지 않아도 오류가 나지않는다, 하지만 기대한 결과가 나오지 않는다


function Hero(name, age){
    this.name = name;
    this.age = age;
    this.say = function() {
        return `My Name is ${this.name}`;
    }
}
var h = new Hero('heecheol', 24);
var u = Hero('unknown', 0); // 에러안남

console.log(h.name); // "heecheol"
console.log(h.age); // 24
console.log(h.say()); // "My Name is heecheol"
console.log(typeof u); // undefined;

/*
생성자함수에 new 를 붙이지 않으면 일반 함수처럼 호출이 되므로 반환값이 포함된다
return문이 없기때문에 u에는 undefined가 할당된다
이 경우의 this는 전역 객체를 참조한다
*/




# 전역객체

* 자바스크립트의 프로그램은 호스트환경 (예: 브라우저)   에서 실행된다
* 호스트환경은 전역 객체를 제공
* 모든 전역 변수는 전역 객체의 속성으로 접근가능
* 생성자 함수에서 new 를 붙이지않으면 this 는 전역객체를 참조하고 this 에 설정된 속성은 window 의 속성이 된다
* new 를 쓰면 새 객체가 반환되고 this 가 새로운 객체를 참조함
* 내장된 전역 함수도 window 객체의 메서드이다


// chrome에서 실행
function Hero(name){
    this.name = name;
}
var h = Hero('heecheol'); // new 를 붙이지 않음
console.log(typeof h); // "undefined";
console.log(typeof h.name); // error! Cannot read property 'name' of undefined

console.log(name); // "heecheol"
console.log(window.name); // "heecheol"
console.log(this.name); // "heecheol"

var h2 = new Hero('heecheolman');
console.log(typeof h2); // "object"
console.log(h2.name); // "heecheolman"

console.log(parseInt('12abc')); // 12
console.log(window.parseInt('12abc')); // 12
console.log(this.parseInt('12abc')); // 12


# 생성자 속성

* 객체가 생성되면 constructor 속성이 백그라운드 객체에 할당
* constructor 속성이 함수에대한 참조이므로 이 함수를 호출해 새 객체 생성가능
* 객체 리터럴 표기법으로 객체를 만든 경우, 객체의 생성자는 Object() 생성자함수다


function Hero(name){
    this.name = name;
}
var h = new Hero('heecheol');
console.log(h.constructor); // function Hero(name){ this.name = name; }
var h2 = h.constructor('heecheolman');
console.log(h2.name); // "heecheolman"

var obj = {};
console.log(obj.constructor); // function Object(){[native code]}

# instanceof 연산자

* instanceof 연산자를 통해 어떤 생성자 함수를 통해 생성되었는지 boolean 타입으로 알려줌


function Hero(){}
var h = new Hero();
var obj = {};

console.log(h instanceof Hero); // true
console.log(h instanceof Object); // true
console.log(obj instanceof Hero); // false
console.log(obj instanceof Object); // true



# 객체 반환 함수


* 일반 함수를 이용해 new 연산자 없이 객체를 생성할 수 있다


function factory(name){
    return {name: name};
}
var obj = factory('obj');
console.log(obj.name); // "obj";
console.log(obj.constructor); // function Object(){[native code]}

this 대신 return 을 써서 constructor 함수의 디폴트 행동을 수정 할 수 있다


function C(){
    this.a = 1;
}
var c = new C();
c.a; // 1;

// 당연한 결과다

function C2(){
    this.a = 1;
    return {b: 2};
}
var c2 = new C2();
console.log(typeof c2.a); // "undefined"
console.log(c2.b); // 2

/*
this객체를 반환하는 대신 b속성을 포함하는 다른객체를 반환함
반환값이 객체일 때만 가능함, 객체가 아닌 다른것을 반환할 경우 this반환

this라는 변수는 함수 맨위에서 정의된 후 마지막에 반환된다고 생각할 수 있다
*/

function C(){
    // var this = {};
    this.a = 1;
    // return this;
}

/*
다시 C2()를 보자면 객체를 반환하려 시도하기때문에 this는 무시된다
C()는 객체의 반환이 없으므로 return으로 this를 반환한다
*/


# 객체 전달

* 객체를 다른 변수에 할당하거나 함수에 전달할 때는 참조만 전달하면된다
* 참조를 변경하면 원본객체도 변경된다
* 함수에 전달할 때도 동일하다


var org = {value: 1};
var chg = org;

console.log(org.value); // 1
console.log(chg.value); // 1

chg.value = 5;

console.log(org.value); // 5
console.log(chg.value); // 5

var func = function(obj){ obj.value = 99; }
func(org);

console.log(org.value); // 99
console.log(chg.value); // 99



# 객체 비교


* 동일한 객체에 대한 두개의 참조일 때만 true

* 서로다른 두 객체가 같은 메서드와 속성을 가지고있으면 false


var one = {code: 1};
var two = {code: 1}; // 애초에 one과 two는 주소가 다르다

console.log(one === two);
console.log(one == two);

var three = one; // three가 one을 가리킨다, 주소가 복사되어서 같은 값을 가리킨다

console.log(one == three);
console.log(one === three);