ㄹhttps://medium.com/tfogo/advantages-and-pitfalls-of-arrow-functions-a16f0835799e#:~:text=The%20takeaway%3A%20Function%20expressions%20are,of%20this%20in%20their%20scope 

 

Advantages and Pitfalls of Arrow Functions

There are big differences between arrow functions and classic function expressions.

medium.com

해당 게시물을 참고해서 번역했습니다.

 

이 글에 들어가기 앞서 먼저 알아두면 좋은 개념을 설명 합니다. 아시는 분은 넘어가도 됩니다. 

 

context : 함수를 호출한 object 

scope : 현재 실행되는 context로 여기서 context는 값과 표현식이 표현되거나 참조 될 수 있는 것을 의미 한다.

 

lexical scope(stactic scope): 함수나 변수의 scope를 호출된 곳이 아닌 정의 된 곳을 기준으로 정함.

dynamic scope : 함수나 변수의 scope를 호출된 라인을 기준으로 정함.

 

this : 함수 내에서 함수를 호출한 context를 뜻한다. 

화살표 함수에서는 자신을 감싼 stactic scope, 전역 코드에서는 global object를 가리킨다 

 

bind

ECMAScript5에서 도입되었습니다.  f.bind(someObject)를 호출하면 f와 같은 본문(코드)과 범위를 가졌지만 this는 원본 함수를 가진 새로운 함수를 생성합니다. 새 함수의 this는 호출 방식과 상관없이 영구적으로bind()의 첫 번째 매개변수로 고정됩니다.

 

 

 

 

일반 함수와 화살표 함수 사이에는 큰 차이가 있습니다. 어떤 상황에서는 훨씬 효과적이지만 어떤 때에는 그렇지 못합니다.

Javascript 화살표 함수는 함수를 작성하는 더욱 효과적인 방법으로  ES2015에서 도입되었습니다.  아래 코드 예시에서 foo와 bar는 같은 기능을 합니다. 

 

let foo = function() {
  console.log('BAZ')
}
let bar = () => {
  console.log('BAZ')
}
foo() // BAZ
bar() // BAZ

 하지만 화살표 함수는 단순히 function 으로 표현되는 함수의 syntactic sugar(같은 기능을 하지만 더 쉽게 작성할 수 있는 새로운 문법)가 아닙니다. 여기엔 반드시 알아야하는 큰 차이가 있습니다. 이 차이는 화살표 함수를 더 멋지게 만들지만, 제대로 알고 쓰지 않으면 문제가 생길 수 있습니다. 이 경우 화살표 함수로 해결할 수 없으므로 function 함수 식을 사용해야 합니다.

 

 

화살표 함수와 this

function 함수 표현에서 this 키워드는 함수가 호출된 context에 따라 바인드 됩니다. 반면 화살표 함수는 lexical scope에서 이 값을 사용합니다. 이 차이로 다른 동작을 하게 됩니다. context는 어떻게 호출되었는지가 중요하고  scope는 어떻게 정의되었는지가 중요합니다.

 

context에 관한 예시입니다. 함수에 의해 method가 정의된 객체를 봐주세요. 

 

let obj = {
  myVar: 'foo',
  
  myFunc: function() {
    console.log(this.myVar)
  }
}obj.myFunc() // foo

obj는 myFunc를 호출합니다. obj는 myFunc의 context입니다. 그래서 myFunc에서 this의 값이 obj에 바인딩됩니다. context는 어떻게 호출되냐에 따라 다르게 정의될 수 있습니다. 예를 들어, constructor가 new 라는 keyword와 함께 호출될 때 this는 생성된 object를 일컫습니다. context에 대한 자세한 사항은 

https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Operators/this 더 보실 수 있습니다.

 

만약 this가 context에 바인드되었다면 (i.e. 함수를 호출한 obect에 바인딩) 이는 callback 함수 사용 시 예상과 다른 결과를 보입니다. 

callback 함수에서 어떻게 동작하는지 보기 위해 setTimeout을 object.myFunc에 추가해보겠습니다.

 

let obj = {
  myVar: 'foo',
  
  myFunc: function() { 
    console.log(this.myVar)   
 
    setTimeout(function() {
      console.log(this.myVar)
    }, 1000)
  }
}obj.myFunc() // foo ... then... undefined

myFunc에서 this의 값은 obj를 가리킵니다. 즉 myFunc.myVar의 결과를 보면 'foo'가 출력됩니다. 그러나 두번째 함수는 setTimeout에 의해 호출됩니다. 여기 context는 다릅니다. 여기서 context는 Node의 Timeout object 또는 브라우저의 window ojbect를 뜻합니다.  그런 이유로 우리는 this를 obj로 생각했지만 결과를 보면 우리가 의도한 this의 값은 undefined로 출력됩니다. 

 

우리가 의도한대로 값을 얻기 위해선 몇가지 방법을 사용해야합니다. 첫번째 방법은  this를 대게 self나 that이라는 이름으로 명명하는 변수에 할당하는 방법입니다. 해당 변수는 callback 함수의 lexical scope안에 있습니다. 이는 callback 함수가 scope안에서 정의되었기 때문에 위에서 만들었던 변수에 접근할 수 있음을 의미합니다.  

 

let obj = {
  myVar: 'foo',
  
  myFunc: function() { 
    let self = this    console.log(this.myVar)  
  
    setTimeout(function() {
      console.log(self.myVar)
    }, 1000)
  }
}obj.myFunc() // foo ... then... foo

우리는 딱봐도 화살표 함수가 callback 함수에 적합하다는 것을 알 수 있습니다. 그러나 우리가 화살표 함수를 object method로 사용하게 된다면 어떻게 될까요 ?

let obj = {
  myVar: 'foo',
  
  myFunc: () => { 
    console.log(this.myVar)  
  }
}obj.myFunc() // undefined

위와 같은 코드를 보면 this가 obj를 말한다고 생각할 수 있습니다. 하지만 여기서 this는 화살표 함수를 호출한 obect에 바인딩하지 않습니다. 화살표 함수는 this의 값을 자기 자신이 정의된 scope의 값을 사용합니다. 여기서는 global object를 일컫습니다. 그래서 화살표 함수는  object method로 사용될 수 없습니다. 

 

function 함수는 object method로 적합하고, 화살표 함수는 callback 함수나 map과 같은 method에 가장 적합합니다.

 

scope에 대해 아래 링크에서 더 읽어보실 수 있습니다. 

https://developer.mozilla.org/en-US/docs/Web/CSS/:scope

 

기본적으로 화살표 함수는 자신의 scope에서 this 값과 다른 값을 바인딩할 수 없습니다. 따라서 bind(), call(), apply() method는 여기의 값에 영향을 주지 않습니다. 

 

생성자(constructor)

화살표 함수가 object에서 제대로 작동하지 않게하는 다른 방법이 있습니다. 이 것들은 constructor가 될 수 없습니다. function 함수 표현식은 새로운 obect를 생성할때 다음과 같이 사용됩니다. 

let Person = function(name, height) {
  this.name = name
  this.height = height
}Person.prototype.hello = function() {
  console.log('Hi, my name is ' + this.name)
}let alice = new Person('Alice', 1.7)
alice.hello() // Hi, my name is Alice​

하지만 화살표 함수는 prototype이라는 property를 가지고 있지 않아서 new와 같이 사용될 수 없습니다. 

 

arguments 바인딩

화살표 함수가 this를 바인딩하지 못하며 단지 자신의 scope의 this 값을 사용한다는 것을 보았다. 화살표 함수는 또한 argument object를 바인딩하지 못한다. function 함수 표현으로는 다음과 같이 할 수 있다. 

let sum = function() {

  // arguments is available return args.reduce((a, b) => a + b, 0)
  let args = Array.from(arguments) 
}
sum(1, 2, 3) // 6

화살표 함수는 arguments object가 없다. 하지만 나머지 연산자를 사용해서 같은 기능을 할 수 있다. 코드는 다음과 같다.  

let sum4 = (...args) => {
  return args.reduce((a, b) => a + b, 0)
}sum(1, 2, 3) // 6

 

암묵적으로 값을 반환 

우리는 위에서 함수를 화살표 함수로  더욱 간결하게 선언할 수 있었습니다. 이 간결한 형식을 사용하면 block에 코드를 감싸지 않아도 됩니다. 함수를 정의하면 화살표 함수가 값을 반환해주기 때문이죠! 

 

let sum = (...args) => args.reduce((a, b) => a + b, 0)

 

또한 개체 리터럴을 괄호로 묶어서 반환할 수 있습니다. 

let getObj = () => ({ foo: 'hello', bar: 'world' })

 

이 간결한 문법은 화살표 함수를 작고 가독성이 좋은 callback 함수를 정의하는 데에 탁월하게 만듭니다. 

 

 

요약

화살표 함수는 기존 function 함수 표현과 꽤 다릅니다. 화살표 함수는 callback 함수와 같이 잘 작동하게 하는 몇가지 탁월한 property가 있습니다. 하지만 object methods나 생성자로 쓰이기엔 적절하지 못합니다. 여기엔 몇가지 차이가 존재합니다. 예를들어 화살표 함수는 generators가 될 수 없습니다.  아래 MDN 문서에서 더 자세하게 보시길 바랍니다! 

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/Arrow_functions   

'Front-End > JavaScript' 카테고리의 다른 글

값의 재할당  (0) 2022.04.14
DOM  (0) 2022.03.23
화살표 함수  (0) 2022.03.23
함수 호이스팅(Hoisting)  (0) 2022.03.23
콘솔을 통해 값 입력 받기  (0) 2022.03.23

키워드

var : 값을 재할당 할 수 있음. 변수에 저장된 값을 다른 값으로 변경하는 변수(variable).

let : 값을 재할당 할 수 있음. 중복선언 불가능. 변수(variable).

const : 값을 재할당 할 수 없음. 중복선언 불가능. 상수(constant). 한번만 할당 가능. 

 

값을 재할당 할때는 새로운 메모리 공간에 값을 저장한다. 이전 값이 저장된 메모리 공간을 지우고 그 메모리 공간에 재할당할 값을 다시 저장하는 것이 아니다. 어떤 식별자도 참조하지 않는 메모리 공간은 가비지 콜렉터에 의해 메모리에서 자동 해제된다. 그 시점을 예측할 수는 없다. JS는 가비지 콜렉터를 내장하고 있는 Managed language로 메모리 누수(Memory leak)를 방지할 수 있다.  

 

Managed language : 언어 차원에서 메모리 할당 및 해제를 해서 메모리 관리.

Unmanaged language : 개발자가 직접 메모리를 할당하고 해제할 수 있다. 대표적으로 C가 있으며 malloc(), free() 함수가 있다. 개발자 역량에 따라 최적의 성능을 낼 수도 있지만 난이도가 높다.

'Front-End > JavaScript' 카테고리의 다른 글

화살표 함수의 장점과 함정  (0) 2022.04.28
DOM  (0) 2022.03.23
화살표 함수  (0) 2022.03.23
함수 호이스팅(Hoisting)  (0) 2022.03.23
콘솔을 통해 값 입력 받기  (0) 2022.03.23

문서 객체 모델(Document Object Model)

 

객체 지향 모델로, HTML이나 XML 문서를 표현하는 구조화된 형식을 말한다.

두 문서의 프로그래밍 인터페이스 역할을 한다.

 

문서의 구조화된 표현을 제공하여 프로그래밍 언어가 문서 구조, 스타일, 내용 등을 변경할 수 있게 한다.

 

HTML DOM

HTML DOM은 HTML 문서를 조작하고 접근하는 표준화된 방법이다. 

HTML DOM으로 모든 HTML 요소에 접근할 수 있다. 

 

XML DOM

XML 문서에 접근하여 그 문서를 다루는 표준화된 방법을 정의한다.

HTML DOM과 마찬가지로 XML문서의 모든 요소에 접근할 수 있다.

 

Document 객체

 

웹페이지를 뜻한다. HTML 요소에 접근하려면 꼭 Document 객체부터 시작해야한다.

 

Document 메소드

 

HTML 요소와 관련된 작업을 도와주는 메소드가 제공된다. 

요소 선택, 생성, 이벤트 핸들러 추가, 객체 선택 등이 가능하다. 

 

HTML 요소(Element)를 선택하기 위해 제공되는 메소드 

메소드 설명
document.getElementById() 해당 아이디의 요소 선택
document.getElementsByClassName() 해당 클래스에 속한 요소 모두 선택
document.getElementByName() 해당 name 속성값을 가지는 요소를 모두 선택
document.querySelectorAll() 해당 선택자로 선택되는 요소를 모두 선택
document.querySelector() 해당 선택자로 선택되는 요소를 1개 선택

getElements , s가 붙은 경우엔 해당하는 경우에 속하면 모두 선택하기 때문에 리스트처럼 [index]를 붙여주면 원하는 곳에 접근할 수 있다.

 

HTML 요소의 생성

메소드 설명
document.createElement() 지정된 HTML 요소를 생성
document.write() HTML 출력 스트림을 통해 텍스트를 출력

document.createElement()는 HTML Object를 생성하고, document.write()는 단순 text를 생성한다.

 

HTML 이벤트 핸들러 추가

속성 설명
Element.onclick=function(){ } 마우스 클릭 이벤트와 연결될 이벤트 핸들러

함수를 따로 정의하고 함수명(인자)만 적을 수도 있다. 

 

DOM 요소의 스타일 변경

 

let selectedElement=document.getElementById('even');

//선택된 요소의 글씨 색 바꾸기
selectedElment.style.color="brown";

위와 같이 바꿔줄 수도 있다.

'Front-End > JavaScript' 카테고리의 다른 글

화살표 함수의 장점과 함정  (0) 2022.04.28
값의 재할당  (0) 2022.04.14
화살표 함수  (0) 2022.03.23
함수 호이스팅(Hoisting)  (0) 2022.03.23
콘솔을 통해 값 입력 받기  (0) 2022.03.23
var food = [
  '마라탕',
  '지삼선',
  '꿔바로우'
];

//리스트 원소의 각 길이를 출력하는 함수 
// console.log(food.map(function(element) {
//     return element.length;
// }));


// 화살표 함수를 이용
console.log(elice.map(element=>element.length));

'Front-End > JavaScript' 카테고리의 다른 글

값의 재할당  (0) 2022.04.14
DOM  (0) 2022.03.23
함수 호이스팅(Hoisting)  (0) 2022.03.23
콘솔을 통해 값 입력 받기  (0) 2022.03.23
자바스크립트 함수  (0) 2022.03.23

함수 선언문을 정의한 줄 이전에서 함수를 호출해도 그 이후에 정의한 함수에서 의도한 대로 답이 출력된다.

이는 함수 선언문형태로 정의한 함수의 유효범위가 코드의 맨 처음부터이기 때문이다.

이를 함수 호이스팅이라고 한다. 아래 코드를 보면 알 수 있다. 

console.log(mul(3,4)); //12

// 함수 선언문 정의
function mul(x, y){
	return x * y;
}
console.log(mul(5, 6)); //30

 

 

하지만 함수표현식 형태로 정의하면 함수 호이스팅을 일어나지 않는다. 예시는 아래와 같다. 

console.log(mul(3,4)); // Uncaught TypeError 발생

// 함수 표현식 형태
var mul=function (x, y){
	return x * y;
}

console.log(mul(5, 6)); //30

 

'Front-End > JavaScript' 카테고리의 다른 글

DOM  (0) 2022.03.23
화살표 함수  (0) 2022.03.23
콘솔을 통해 값 입력 받기  (0) 2022.03.23
자바스크립트 함수  (0) 2022.03.23
자바스크립트 코드에 html 태그 쓰기  (0) 2022.03.23

자바스크립트에서 콘솔을 통해 값을 입력 받기 위해서는 먼저 readline 모듈을 이용해야한다.

readline 모듈은 한 번에 한 줄씩 Readable Stream에서 데이터를 읽기 위한 인터페이스를 제공한다. process.stdin 을 예로 들 수 있다. 아래와 같이 접근할 수 있다. 

const readline=require("readline");

 

그 다음, readline 모듈을 이용해 입출력을 위한 인터페이스 객체를 만든다.

//입출력을 위한 인터페이스 객체 생성
const rl =readline.createInterface({
    input:process.stdin,
    output:process.stdout,
});

 

 

위에서 입출력을 위해 생성한 인터페이스 객체 r1은 아래와 같이 사용할 수 있다. line을 통해서 입력이 들어온다. 함수 밖에 빈 리스트 input을 선언하고 여기에 공백을 기준으로 입력받은 값을 저장한 line을 할당한다. rl.close()를 통해 입력을 종료할 수 있다. 

 

(line)=>{...}은 funtion(line){...}와 같다. 

 

var input=[];

rl.on("line", (line)=>{
    input=line.split(' ');
    rl.close();
});

rl.on('close', ()=>{
    console.log(input);
})

 

전체 코드는 아래와 같다.

const readline=require("readline");

//입출력을 위한 인터페이스 객체 생성
const rl =readline.createInterface({
    input:process.stdin,
    output:process.stdout,
});

var input=[];

rl.on("line", (line)=>{
    input=line.split(' ');
    rl.close();
});

rl.on('close', ()=>{
    console.log(input);
})

 

 

 

'Front-End > JavaScript' 카테고리의 다른 글

화살표 함수  (0) 2022.03.23
함수 호이스팅(Hoisting)  (0) 2022.03.23
자바스크립트 함수  (0) 2022.03.23
자바스크립트 코드에 html 태그 쓰기  (0) 2022.03.23
객체(object)  (0) 2022.03.23

+ Recent posts