본문 바로가기
Today I learned

2021 03 12 - 화살표 함수의날.

by soheemon 2021. 3. 12.

arrow function expression

developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Functions/Arrow_functions#%EB%B8%8C%EB%9D%BC%EC%9A%B0%EC%A0%80_%ED%98%B8%ED%99%98%EC%84%B1

 

vue.js를 익히며 가장 큰 숙제로 다가온 arrow function.

 

function 표현과 비교

- 구문이 짧다

- this, arguments, super 또는 new.target을 바인딩 하지 않는다.

- 항상 익명이다.

- 메소드 함수가 아닌곳에 적합하다. 따라서 생성자로서 사용할 수 없다.

 

* 기본구문

// 1) 매개변수 여러개 받기 & 로직이 2줄 이상인경우..
(param1, param2) => {statement}

// 2) 단순히 return만 하고 끝날때 
// {return expression}과 같다. 
(singleParam) => expression

// 3) 매개변수가 하나뿐인 경우 괄호는 선택사항
param => {statement}

* 고급구문

// 객체 리터럴을 반환하기  위해서는 함수 본문을 괄호속에 넣는다.
param => ({foo: bar})

/*
아래의 표현과 일치한다.
  (function (param) {
    return {
      foo: bar
    };
  });
/*

// 나머지 매개변수, 기본 매개변수를 지원한다.
(param1, param2, ...rest) => {statement}
(param = defaultValue, param2 = defaultValue) => {statement}

var f = ([a, b] = [1, 2], {x: c} = {x: a + b}) => a + b + c;
f() //6

 

 

=> 와 this는 뗄래야 뗄 수 없는 사이..

간단하게 기억해야 할것 ! 화살표 함수의 this에는 화살표 함수가 생성 된 컨텍스트와 동일한 값이 있습니다.

내부 화살표 함수 의 값 은 항상 둘러싸는 범위에서 상속됩니다.

 

 

this 다시 둘러보기...

  • 대부분의 경우 this의 값은 함수를 호출한 방법에 의해 결정된다.
  • ES5는 함수를 어떻게 호출했는지 상관하지 않고 this값을 설정 할 수 있는 bind메서드를 도입했고
  • ES2015는 스스로의 this 바인딩을 제공하지 않는 화살표 함수를 추가했다!

 

// if 블럭에는 context가 생성될까요?
if(true) {
	this	// 여기서 this는 무엇일까. window!
}

// 객체에 속하지 않는 함수 안에서는 this가 무엇을 가리킬까요?
function myFunc(){
	this
}

 

실행 컨텍스트(global, function 또는 eval)의 프로퍼티는 비엄격 모드에서 항상 객체를 참조한다.

+엄격 모드에서는 어떠한 값이든 될 수 있다.

 

function myFunc(){
	return this
}
myFunc() === window;	//true

//반면 엄격모드에서는 "실행 문맥에 진입하며 설정되는 값을 유지하므로" this는 undefined다.

function myFunc(){
	"use strict"
	return this
}
myFunc() === undefined;	//true

bind 메서드

this를 인자로 보낸다.. bind로 보낸 this가 함수 안에서 호출된다...

그러면 bind를 이용해서 함수를 호출할때 매개변수는 어떻게 넘길까?

첫번째 매개변수를 thisArg로 받고, 나머지는 그대로 함수에 전해준당.

function f(){
	return this.a;
}

f();	// undefined. this는 window라서.

var g = f.bind({a:'testtest'})	// this를 매개변수로 넘긴 객체로 바인딩
console.log(g())	//testtest

var h = g.bind({a: 'soheemon'})	//testtest. bind는 한번만 동작한다!

또한 bind함수는 한번만 바인딩 할 수 있다.

 

+ 추가

환장하는 this

this.x = 9;
var module = {
  x: 81,
  getX: function() { return this.x; }
};

module.getX(); // 81

var retrieveX = module.getX;
retrieveX();
// 9 반환 - 함수가 전역 스코프에서 호출됐음

객체 안에 선언된 메서드라도, 전역 스코프에서 호출되면 this를 전역으로 참조한다.

 

다시 arrow function으로 돌아와서...

 

화살표 함수에서 this는 자신을 감싼 정적범위(lexical context)이다. 만약 전역이라면 전역 객체를 가리킨다.

var globalObject = this
var foo = (() => this)	//전역에 선언되어있다면 전역 this를 가진다.
console.log(foo() === globalObject) // true

 

화살표 함수는 일반 변수 조회 규칙을 따른다. 현재 범위에서 존재하지 않은 this를 찾으면 화살표 함수는 바로 바깥 범위에서 this를 찾는다.

조건 화살표함수 익명함수
객체로서 메서드 호출

var globalObj = this
var obj = {func : () => this}

console.log(globalObj === obj.func())

//true. 
var globalObj = this
var obj = {func : function(){
 return this
}}

console.log(globalObj === obj.func())

//false. 여기서의 this는 obj를 가리킨다.
Class안에서 비동기 함수로 호출시 this function Person(){
 this.age = 0;
 setInterval(() => {
  this.age++;;
}, 1000 )
}

var p = new Person();
// 여기서 setInterval 타이머 만료후 실행되는 growUp함수의 this는 Person 객체를 가리키게 된다.
function Person(){
 this.age = 0;
 setInterval(function grouUp(){
  this.age++;;
}, 1000 )
}

var p = new Person();
// 여기서 setInterval 타이머 만료후 실행되는 growUp함수의 this는 window 함수를 가리키게 된다.

ECMAScript 3/5 에서는, 이 문제를 this 값을 폐쇄될 수 있는 (비전역) 변수에 할당하여 해결했습니다.

function Person(){
 this.age = 0;
that.age = 0;
 setInterval(function grouUp(){
  // 콜백은 `that`변수를 참조하고한다. 약간 클로저 너낌인데....?
  that.age++;;

}, 1000 )
}
바인딩 되지 않은 arguments var arguments = [1, 2, 3];
var arr = () => arguments[0];

arr(); // 1

function foo(n) {
  var f = () => arguments[0] + n; // foo's implicit arguments binding. arguments[0] is n
  return f();
}

foo(1); // 2

+ 대안
function foo (n) {
 var f = (...args) => args[0] + n
 return f(2)
}
foo(1); //3
 
객체 안에서의 메서드 var obj = {
 i: 10,
 b: () => console.log(this.i, this),
 c: function(){
 console.log(this.i, this)
 }
}
obj.b(); // prints undefined, Window {...} (or the global object)
obj.c(); // prints 10, Object {...}

b는 호출될때 해당 위치의 this이다!
 
     
var func = () => {  foo: 1  };
// func() 호출은 undefined를 반환!
// var func = () => ({ foo: 1 }); ()로 한번 감싸야한다.!

var func = () => {  foo: function() {}  };
// SyntaxError: function 문은 이름이 필요함!

 

'Today I learned' 카테고리의 다른 글

2021 독서목록  (2) 2021.03.26
2021 03 15 - vue Router  (0) 2021.03.15
2021 03 11 - vuex 빨리보기  (0) 2021.03.11
2021 03 08 - ES6 둘러보기  (1) 2021.03.08
2021 03 02 -  (0) 2021.03.02

댓글