[JavaScript] ES6 chap.2

 

 

 

default parameter & arguments

- default parameter

function 더하기 (a, b = 10){ // b에 default 값을 부여한다. 연산이나 함수 사용 가능
  console.log(a + b)
}

더하기(1); // 11
더하기(1, 3); // 4

 

- arguments

function 함수(a,b,c){
  console.log(arguments);
}

함수(2,3,4); // [2, 3, 4]....arguments
function 함수(a,b,c){
  for(var i=0; i<arguments.length; i++){
  	console.log(arguments[i]); // 반복문으로 함수의 파라미터 조회
  }
}

함수(2,3,4);

 

 

 

Rest Parameter

ES6에 추가된 arguments랑 비슷한 용도의 파라미터 (나머지 파라미터)

function 함수2(...파라미터들){
  console.log(파라미터들)
}

함수2(1,2,3,4,5,6,7); // [1, 2, 3, 4, 5, 6, 7]

arguments와의 차이점은 arguments는 함수를 사용할 때의 파라미터의 갯수가 변경되면 기존 함수의 파라미터 갯수도 변경 해야하지만 rest parameter는 유동적으로 변경 가능하다.

 

function 함수2(a, b, ...파라미터들){
  console.log(파라미터들)
}

함수2(1,2,3,4,5,6,7); // [3, 4, 5, 6, 7]



// 주의
function 함수2(a, ...파라미터들, b){
  console.log(파라미터들)
} // ...파라미터 뒤에 또 다른 파라미터가 오면 에러 발생

function 함수2(a, ...파라미터들, ...파라미터들2){
  console.log(파라미터들)
} // rest 파라미터를 중복으로 써도 에러 발생

 

 

 

Primitive data type / Reference data type

* primitive data type

- 자료 자체가 변수에 저장되는 자료 (문자, 숫자, 문자열 등)

var 이름1 = '김';
var 이름2 = 이름1;
이름1 = '박';
console.log(이름1); // 박
console.log(이름2); // 김

 

 

* reference data type

- 자료가 변수가 아닌 컴퓨터 메모리에 저장되고 참조하여 사용하는 자료 (Array, Object 등)

var 이름1 = { name: '김'};
var 이름2 = 이름1;
이름1.name = '박';
console.log(이름1.name); // 박
console.log(이름2.name); // 박

primitive 타입과 달리 reference 타입은 데이터가 저장된 것이 아니라 참조한다는 값을 가리키는 값이 저장된 것이기 때문에 참조되는 데이터를 변경하게 되면 두 변수가 가리키는 값은 같다.

 

 

- cf

var 이름1 = { name : '김' };
var 이름2 = { name : '김' };

console.log(이름1 == 이름2); // false
console.log(이름1 === 이름2); // false
console.log(이름1.name == 이름2.name); // true

위 처럼 새로운 {}를 할당할 때, 새로운 object가 생성되기 때문에 {} 안에 있는 오브젝트 데이터는 같지만 서로 다른 object이며 다른 object를 각각 가리키고 있는 것이다.

 

var 이름1 = { name : '김' };

function 변경(obj){
  obj = { name : 'park' }; // obj라는 변수에 새로운 {} object 재할당
  obj.name = 'park' // 파라미터로 들어온 object의 name의 value 변경
}

변경(이름1);

 

 

 

constructor

기존의 object 생성 방식

var 학생1 = { name : 'Kim', age : 15 };
var 학생2 = { name : 'Park', age : 15 };
...

여러번 선언하고 정의하거나 복사를 해야하는데 복사하는데 있어서 데이터가 같은 값을 참조 할 수 있기 때문에 constructor 방식으로 object를 생성할 수 있다.

 

 

* constructor

function 기계(이름){ // 기계: constructor
  this.name = 이름; // instance
  this.age = 15; // instance
  this.sayHi = function(){ // instance
    console.log('안녕하세요' + this.name + ' 입니다');
  }
}
var 학생1 = new 기계('Park');
var 학생2 = new 기계('Kim');

function이라는 함수를 정의하고 해당 함수를 new 함수() 형태로 사용한다. 어떤 변수에 기계라는 함수를 new 기계()로 할당하게되면 기계는 constructor가 되며 기계() 안에 있는 this는 instance가 되어 여러가지의 object를 생성할 수 있다.

 

 

 

prototype

prototype = 유전자의 역할

function 기계(){
  this.name = 'Kim';
  this.age = 15;
}
var 학생1 = new 기계(); // 상속의 개념 => 기계의 name과 age를 사용할 수 있음

console.log(기계.prototype); // 내부에 prototype이라는 항목이 생성

학생1이 기계의 constructor가 가진 name과 age의 instance를 사용할 수 있게되는 것을 상속(inheritance)했다고 한다. 하지만 constructor말고도 상속기능을 구현할 수 있는데 Java와 같은 다른 언어의 상속(extend)의 개념과 달리 Javascript는 prototype의 개념을 사용한다.

 

new 기계()를 생성하게되면 표면적으로 보이지 않는 내부의 공간에 prototype이라는 공간이 생성되는데 이것은 부모의 유전자 역할을 한다.

 

 

function 기계(){
  this.name = 'Kim';
  this.age = 15;
}

기계.prototype.gender = '남';
var 학생1 = new 기계();
var 학생2 = new 기계();

console.log(학생1.gender); // 남
console.log(학생2.gender); // 남

기계라는 부모의 prototype(유전자)에 {gender: '남'} 이라는 속성을 추가하게되면 기계를 상속한 학생1, 학생2 자식은 {gender: '남'}이라는 속성을 사용할 수 있다.

 

 

* 작동원리

- 자바스크립트는 오브젝트에서 값을 출력할 때

  • 학생1에 gender라는 값이 있는가 ?
  • 기계라는 부모 유전자에 gender라는 값이 있는가 ?
  • 그럼 그 부모의 유전자에 gender라는 값이 있는가 ?
  • ...

 

// Array 생성 시
var arr = [1,2,3];
// == var arr = new Array(1,2,3);

// Object 생성 시
var obj = {name: 'kim'}
// == var obj = new Object({name: 'kim'});

Array나 Object 등의 생성 방식의 차이일 뿐 결국엔 내부에선 constructor 방식으로 생성되기 때문에 해당 object에 prototype으로 저장 되어있는 내장 함수 또한 사용할 수 있다.

 

 

** prototype과 constructor의 차이

  • constructor: 자식들이 직접 값을 소유하게 하기
  • prototype: 부모만 가지고 있고 그걸 참조해서 쓰게 하기

 

 

 

* 특징

1. prototype은 constructor 함수에만 몰래 생성된다.

 - 일반 object, array엔 prototype 없음 (constructor 함수, Object.create(), class 써야 함)

 

 

2. 부모 유전자 찾기

function 기계(){
  this.name = 'Kim';
  this.age = 15;
}
var 학생1 = new 기계();
console.log(학생1.__proto__); // 기계
console.log(기계.prototype);

 - 부모의 의해 생성된 자식엔 __proto__라는 속성이 있는데 해당 속성은 자식의 부모 object를 찾아준다.

 

 

3. __proto__를 직접 등록하면 object끼리 상속기능 구현가능

var 부모 = { name : 'Kim' };
var 자식 = {};

자식.__proto__ = 부모;
console.log(자식.name); // Kim

 

 

4. 자바스크립트는 모든게 다 Object이다.

- __proto__로 계속 올라가다보면 모든 부모는 Object라는 constructor로 통한다.

 

 

 

상속

* ES5

- Object.create()

var 부모 = { name : 'Kim', age : 50 };
var 자식 = Object.create(부모);
자식.age  = 20;

var 손자 = Object.create(자식);

console.log(손자.age); // 20 ==> 자식의 age

손자에서 age를 호출하면 자식의 속성에 age가 있는지 확인하고 있으면 그 것을 사용하지만 없다면 부모로 올라가서 age가 있는지 확인하는 순서이기 때문에 자식의 age 값은 20으로 되어있어 20이 출력된다.

 

 

* ES6

- class

class 부모 {
  constructor(){
    this.name = 'Kim';
    this.sayHi = function(){ console.log('hello') } // constructor안에 추가하기
  }
  sayHi = function(){ console.log('hello') } // prototype에 추가하기
  // == sayHi(){ console.log('hello') } // prototype에 추가하기
}

var 자식 = new 부모();

function말고도 constructor를 만드는 ES6의 방식. constructor 안에 있는 인스턴스를 만들어 사용할 수 있으며 그 외부에 만들면 prototype으로 사용할 수 있다.

 

 

* Object.getPrototypeOf()

함수 안에 object를 넣으면 부모 prototype을 출력할 수 있다. (__proto__랑 유사함)

 

 

 

extends & super
class 할아버지{
  constructor(name){
    this.성 = 'Kim';
    this.이름 = name;
  }
  sayHi(){
    console.log('안녕 나는 할아버지')
  }  
}

class 아버지 extends 할아버지{ // 할아버지라는 객체의 특성을 복사할 때 사용
  constructor(name){
    super(name); // 할아버지 객체의 속성들을 사용하기위해 선언
    this.나이 = 50;
  }
  sayHi2(){
    console.log('안녕 나는 아버지');
    super.sayHi();
  }
}

var a = new 아버지('만수');
a.sayHi2(); // 안녕 나는 아버지 안녕 나는 할아버지

 

 

할아버지 객체의 속성들을 아버지 객체에 복사하기 위해 extends를 사용한다. extends를 사용하게 되면 따라오는 super라는 예약어가 있는데 super는 부모 객체의 속성들에 접근하는 것이다.

 

super는 constructor 안에서 사용하면 부모(할아버지) class의 constructor이고 prototype 함수 안에서 쓰면 부모(할아버지) class의 prototype이다.

 

 

 

getter & setter

자바스크립트의 getter, setter는 오브젝트 내의 데이터의 무결성을 보존하기 위해 쓰는 키워드이다.

var 사람 = {
  name : 'Kim',
  age : 30,
  nextAge(){
    return this.age + 1  
  }
  setAge(나이){
    this.age = parseInt(나이);
  }
}

console.log(사람.nextAge()); // 31
console.log(사람.setAge(20)); // 20

: 함수로 데이터 꺼내오기

- object 안의 데이터가 복잡할수록 함수로 만들어 데이터를 꺼내기 쉽다.

- 내부에 있는 인스턴스 변수를 건드리지 않아 수정 시 실수를 방지할 수 있다.

 

: 함수로 데이터 수정하기

- 원본 데이터를 덮어쓰지 않고 카피 데이터로 관리할 수 있다.

- 내부에 있는 인스턴스 변수를 건드리지 않아 수정 시 실수를 방지할 수 있다.

 

 

* get, set 사용

var 사람 = {
  name : 'Kim',
  age : 30,
  get nextAge(){
    return this.age + 1  
  }
  set setAge(나이){
    this.age = parseInt(나이);
  }
}

console.log( 사람.nextAge );
console.log( 사람.setAge = 20 );

get, set을 이용하면 오브젝트 내의 함수들을 괄호 없이 사용할 수 있다.

 

 

* 사용하는 기준

- 데이터를 뽑거나 가져올 때는 get, 데이터를 입력하거나 수정할 때는 set을 쓰면 된다.

get: 함수에 파라미터가 있으면 안되며 함수 내에 return이 있어야 한다.

set: 함수는 입력을 받아 수정을 해줘야 하기 때문에 파라미터가 한개 이상 꼭 존재해야 한다.

 

class 사람 {
  constructor(){
    this.name = 'Kim';
    this.age = 30;
  }
  get nextAge(){
    return this.age + 1  
  }
  set setAge(나이){
    this.age = parseInt(나이);
  }
}

var 사람1 = new 사람();

console.log( 사람.nextAge );
console.log( 사람.setAge = 20 );

마찬가지로 class에서도 사용할 수 있다.

 

 

 

 

'JavaScript' 카테고리의 다른 글

[JavaScript] 함수형 프로그래밍 (일급함수, 고차함수)  (0) 2022.03.29
[JavaScript] ES6 chap.3  (0) 2021.12.02
[JavaScript] ES6 chap.1  (0) 2021.11.29
[JavaScript] Chap.2  (0) 2021.11.25
[JavaScript] Chap.1  (0) 2021.11.19

+ Recent posts