[DAY13] 함수 와 객체 와 인스턴스 와 프로토타입 와..

Jhey·2024년 10월 30일
1

JavsScript

목록 보기
8/18

0. 함수와 객체

객체를 함수를 통해 아래처럼 정의할 수 있다.

function User(){
	this.name = "철수"
	this.age = 30;
}

0.1 생성자 함수

  • 한 번 정의해놓으면 다양하게 내용을 바꿔가며 사용 가능
  • 유지보수에 장점이 있다
function User(){
	this.name = "철수"
	this.age = 30;
}

// **new**를 사용하면 **user** 함수가 객체로 취급이 된다.
const user = new User();
// user {name: "철수"} 생성자 이름이 앞에 생김

0.2 this

  • 생성자 함수 내부에서 this는 새로 생성되는 인스턴스를 가리킨다.

  • this를 통해 인스턴스의 속성이나 메서드를 설정하면, 각각의 인스턴스마다 고유한 속성과 메서드를 가질 수 있다.

  • new 키워드를 쓰지 않고 호출하면 this가 전역 객체(브라우저 환경에선 window)를 참조하게 되어, 속성이 의도하지 않은 곳에 설정될 수 있다. 생성자 함수는 항상 new와 함께 호출하는 게 중요하다.


0.3 인스턴스

  • new로 만든 생성자 함수가 담긴 변수
  • 상위 객체의 메서드를 자신의 것처럼 호출한다.
// 매개변수를 넘겨서 객체를 생성할 수 있다.
// 객체 리터럴보다 효율적이다
function Car(name, color){
	this.name = name
	this.color = color
	this.getInfo = function(){
		return `${this.name} ${this.color}`
	}
}
// **인스턴스**
const car1 = new Car("b", "white")
car.getInfo()

0.3 인스턴스 객체의 속성 private 하게 사용하기

생성된 인스턴스를 통해 외부에서 속성에 접근이 가능하다. 그렇기 때문에 보안에 취약할 수 있다. 이를 private 패턴을 적용하여 보완한다

  1. this 변수를 일반 변수로 변경
  2. prototype 함수생성자 내부로 위치 변경
// **private 패턴, 클로저 패턴**
// 단점 proto 타입을 만들 수 없다
function Counter(){
	let count = 0; // 일반 멤버로 만들면 객체에 속성이 등록이 안된다
	
	this.increment = function(){
		count++;
	}
	
	this.decrement = function(){
		count--;
	}
	
	this.getcnt= function(){
		return count;
	}
}

const counter = new Counter();
counter.count  = 10 // 전혀 영향 주지 못함

1. 프로토타입

1.1 사용 이유

객체의 속성은 하나하나 메모리에 저장된다. 이때 반복적이고 변동성이 없는 속성이 많아질수록 메모리 누수가 발생한다. 이를 막기 위해 프로토타입을 사용한다.


1.2 정의

  • 변동성이 없고 공통적인 기능(함수, 속성 등)을 프로토타입에 넣는다.

  • 화살표 함수는 프로토타입이 없다.

  • 프로토타입함수 선언문에서만 존재한다.

  • 프로토타입함수와 1 : 1로 매치되는 공간이다.

function Car(name, color){
	this.name = name
	this.color = color
}
// 공통적인 기능인 getInfo를 프로토타입에 넣는다.
Car.prototype.getInfo = function(){ 
	return `${this.name} ${this.color}`
}

1.3 프로토타입 체인

인스턴트에서 자신이 속한 생성자 함수의 프로토타입에 접근하는 방법
인스턴스가 프로토타입 객체를 탐색해 나가는 과정


1.3.1 표준 내장 객체로 이해하기

function Car(name, color){
	this.name = name
	this.color = color
}
const car1 = new Car("b", "white");
car1.hasOwnProperty("color") // <--- 왜 사용 가능 ?

우리가 사용하는 hasOwnProperty 메서드는 왜 사용이 가능할까?
우리가 선언한 인스턴스 car1의 생성 함수에는 hasOwnProperty 관련 메서드가 하나도 없다.
➡️ 프로토타입 체인 때문에 가능


1.3.2 표준 내장 객체 접근하기

수코딩(https://www.sucoding.kr)

  1. 생성자 함수 1이 만들어진다.

  2. 1의 프로토 타입 3이 만들어진다.

  3. 1인스턴스 2는 프로토타입 체인을 통해 1에 연결된 프로토타입 3에 접근한다.

  4. 하지만 프로토타입 3에는 직접적으로 hasOwnProperty 메서드가 없다.

  5. hasOwnProperty는 최상위 객체인 Object 5의 프로토타입 4에 있다.

  6. 그래서 프로토타입 3은 프로토타입 체인을 통해 최상위 프로토타입 4에 접근한다.

  7. 4에는 드디어 hasOwnProperty 메서드가 존재한다.

➡️ 이렇게 최하위 인스턴스에서 최상위 프로토타입에 접근할 수 있는 것이 프로토타입 체인이다.


1.4 프로토타입도 누군가의 인스턴스

프로토타입은 최상위 프로토타입의 인스턴스다.

❓ 프로토타입이 어떻게 인스턴스일까?

  • 인스턴스는 "new로 만든 생성자 함수가 담긴 변수"이다.
    하지만 프로토타입은 이미 만들어져 있기 때문에 위 개념과는 동떨어진다. 뿐만 아니라 프로토타입은 new 키워드로 만드는 인스턴스도 아니다. 위 개념의 인스턴스에는 프로토타입이 인스턴스라는 내용이 포함되지 않는다.

  • 하지만 다음과 같이 인스턴스 여부를 조회해보면 true가 나온다.
    Object의 인스턴스는 맞다.

    function MyFunction() {}
    console.log(MyFunction.prototype instanceof Object); // true
  • 그래서 인스턴스의 좀 더 넓은 의미를 찾아보았다.

    인스턴스처럼 작동한다는 말은, 프로토타입 체인에서 상위 프로토타입의 속성과 메서드가 하위 객체에도 마치 자신의 것처럼 활용된다는 의미다.

➡️ 하위 프로토타입이 결국 상위 프로토타입의 속성과 메서드를 자신의 것처럼 활용하니까 상위 프로토타입의 인스턴스 = 하위 프로토타입이라고 할 수 있다.


1.5 래퍼 객체(wrapper object)

const PI = 1243253.12323
PI.toFixed(2) //왜 객체도 아닌데 내장함수를 사용할까?
  • 자바스크립트 엔진이 기본 자료형의 값을 객체처럼 다루기 위해서 만든 객체

  • 그 자료형과 관련 있는 생성자 함수의 인스턴스 객체로 감싼다.

  • 일시적이며, 끝나면 사라진다.




배운 점

  1. 처음으로 자바스크립트 객체인스턴스 프로토타입을 자세히 공부해봤다. 이름만 보고 무서워서 도망가기 바빴는데, 막상 공부해보니 모두 연결된 개념이라 놀랍고 평소 사용하던 메서드가 이런 개념을 가졌다는 걸 알게 돼서 흥미롭다.
profile
천천히 가더라도 즐겁게 ☁

0개의 댓글

관련 채용 정보