[240408] ES6 함수의 추가 기능

  • ES6 이전의 모든 함수는 일반 함수, 생성자, 메서드로서 호출 할 수 있었다. 사용 목적에 따라 구분 X
    • 모든 함수가 callable 면서 constructor 이었음
    • callable 호출할 수 있는 함수 객체
    • constructor 인스턴스를 생성할 수 있는 함수 객체
    • 불필요한 프로토타입 객체 생성
  • ES6 에서는 함수의 목적에 따라 세 가지 종류로 구분
ES6 함수의 구분 constructor prototype super arguments
일반함수 O O X O
메서드 X X O O
화살표 함수 X X X X

메서드

  • ES6 사양에서 메서드는 메서드 축약 표현으로 정의된 함수만을 의미
    • 이전에는 객체에 바인딩된 함수를 의미로 사용
const obj = {
	x: 1,
	// foo 는 메서드다.
	foo() { return this.x; }
	// bar에 바인딩된 함수는 메서드가 아닌 일반 함수
	bar: function() { return this.x; }
}; 

console.log(obj.foo()); // 1
console.log(obj.bar()); // 1
  • 메서드는 인스턴스를 생성할 수 없는 non-constructor 임
new obj.foo(); // TypeError: obj.foo is not a constructor
new obj.bar(); // bar {}
  • 인스턴스를 생성할 수 없으므로 prototype 프로퍼티가 없고, 프로퍼티타입도 생성하지 않음
obj.foo.hasOwnProperty('prototype'); // false
obj.bar.hasOwnProperty('prototype'); // true
  • 참고로표준 빌트인 객체가 제공하는 프로토타입 메서드와 정적 메서드는 모두 non-constructor
  • 메서드는 자인을 바인딩한 객체를 가리키는 내부 슬롯 [[HomeObject]] 가짐
    • super 참조는 [[HomeObject]] 를 사용하여 수퍼 클래스의 메서드를 참조
    • super 키워드 사용 가능
    • ES6 메서드가 아니면 [[HomeObject]] 갖지 않음
  • 메서드를 정의할 때 ES6 이전의 방식 비추 (의미적으로 맞지 않는 constructor 제거하고 super 추가 했기 때문)

화살표 함수

  • 표현도 간략한데, 내부 동작도 간략함
  • 콜백 함수 내부에서 this 가 전역 객체를 가리키는 문제를 해결하기 위한 대안으로 유용

1. 정의

const arrow = (x,y) => { ... }; 
const arrow2 = x => { ... }; 
const arrow3 = x => x**2; 
// 객체 리터럴을 반환하는 경우 소괄호로 감싸 주어야함
const arrow4 = (id,content) => ({id, content}); 

2. 일반 함수와 차이

  • non-constructor
  • 중복된 매개변수 이름을 선언할 수 없다.
    • 일반함수도 strict mode 에서는 에러 발생함
  • 화살표 함수는 함수 자체의 this, arguments, super, new.target 바인딩을 갖지 않는다.
    • 스코프 체인을 통해 상위 스코프 참조
    • 화살표끼리 중첩되어있으면 화살표가 아닌 가장 가까운 상위 함수 중에서 참조함

3. this

  • 가장 구별되는 큰 특징
  • 다른 함수 인수로 전달 되는 경우가 많음
  • 일반 함수는 함수를 정의할때가 아닌, 어디서 호출했냐에 따라 this 객체가 동적으로 결정된다.
class Prefixer {
	constructor(prefix) {
		this.prefix = prefix;
	}
	
	add(arr) {
		return arr.map(function (item) {
			return this.prefix + item; // this undefined 가리킴
			// map 메서드가 콜백함수를 일반 함수로서 호출하기 때문
		});
	}
}

const prefixer = new Prefixer('-webkit-');
console.log(prefixer.add(['transition', 'user-select']));

방안

  • this 를 다른 변수 값에 넣고 난 뒤 사용
  • Array.prototype.map 두번째 인수로 this 전달
  • prefixer 객체를 가리키는 this를 바인딩
add(arr) {
	return arr.map(function (item) {
		return this.prefix + ' ' + item;
	}.bind(this));
  • 화살표 함수 사용

화살표함수는 ?

  • 함수 자체의 this 바인딩 존재 X
  • 화살표 함수는 상위 스코프의 this 참조한다.
  • 메서드를 화살표 함수로 정의해야하는 것은 피해야한다 ( ES6 메서드 말고 일반적인 메서드 의미)
const person = {
	name: 'Lee',
	sayHi: () => console.log(`Hi ${this.name}`);
	
	// window.name 과 같음
	person.sayHi(); // Hi
  • 메서드를 정의할때는 ES6 메서드(축약표현)을 쓰자.

4. super

  • 마찬가지로 상위 스코프의 super 참조
  • super 바인딩 갖지 않는다.
  • super 참조해도 에러 발생 X , constructor super 바인딩을 참조함

5. arguments

  • 마찬가지로 상위 스코프의 arguments 참조
  • 바인딩을 갖고 있지 않는다.

Rest 파라미터

1. 기본 문법

  • … 점 세개를 붙여서 함수에 전달된 인수 목록을 배열로 전달 받음
function foo(...rest) {
	// 매개변수 rest 는 인수들의 목록을 배열로 전달받는 Rest 파라미터다.
	console.log(rest) // [ 1, 2, 3, 4, 5 ]
}

foo(1,2,3,4,5);
  • rest 는 하나만 선언 가능
  • 반드시 마지막 파라미터이어야 함
  • 함수 객체의 length 에 영향을 주지 않는다.

Rest 파라미터와 arguments 객체

  • arguments 객체
    • 순회 가능한 유사 배열 객체
    • 함수 내부에서 지역 변수처럼 사용 가능
    • 배열이 아니기때문에 배열 메서드를 사용하려면 Function.prototype.call , Function.prototype.apply 메서드를 이용해 객체로 바꾸어줘야함
  • rest 파라미터
    • 가변 인자 하무의 인수 목록을 배열로 직접 전달 받을 수 있음
  • 화살표 함수는 arguments 객체 없기때문에 rest 파라미터 이용해야함

매개변수 기본값

  • ES6 에서 도입
  • rest 는 기본값 지정 불가능
function sum(x=0, y=0) {
	return x + y;
}
  • length 프로퍼티와 arguments 객체에 영향 X
function sum(x,y=0) {
	console.log(arguments);
}

console.log(sum.length); // 1 

sum(1); // Argumnets {'0': 1 } 
sum(1,2); // Argumnets {'0': 1, '1':2 } 

Categories:

Updated:

Leave a comment