ES6+ 향상된 함수 기능 (2) - Arrow function


ES6에서 함수의 기능을 온전하게 완성했다고 볼 수 있다.

 - 매개변수에 기본값을 줄 수 있게 됨.

 - 나머지 매개변수를 통해 가변 길이 매개변수를 좀 더 명시적으로 표현할 수 있음.

 - Named parameter(명명된 매개변수)를 통해서 함수를 호출하는 코드의 가독성이 훨씬 좋아졌다.

 - Arrow function(화살표 함수)가 추가되면서 함수 코드가 간결해졌고, this 바인딩에 대한 고민을 덜 수 있게 되었다.


1.  함수를 정의하는 새로운 방법 


#1 Arrow fucntion (화살표 함수) 간단 사용법


ES6부터 함수를 정의하는 방법이 하나 추가되었다.

이 Arrow function을 이용하면 함수를 간결하게 작성할 수 있다.


const plus = (a,b) => a+b;
console.log(plus(1,2)); // 3
const plus10 = (a) => a + 10;
console.log(plus10(5)); // 15
const plusReturnObj = (a,b) => ({result: a+b});
console.log(plusReturnObj(2,5)); //{result: 7}

plusplus10의 경우처럼 중괄호를 생략하면 계산의 결괏값이 리턴이 된다.

return 키워드 또한 생략할 수 있다.

plusReturnObj의 경우처럼 객체를 반환하기 위해서는 () 소괄호로 감싸야 한다.



#2 Arrow fucntion (화살표 함수)의 코드가 여러 줄인 경우


코드를 { } 중괄호로 감싸고 return 키워드를 사용한다.


const plus = (a, b) => {
if(!a || !b){
throw new Error('zero is not applicable');
}
return a+b;
};



#3 this 와 arguments가 바인딩 되지 않는 Arrow fucntion



Arrow function에서는 thisarguments를 사용할 수 없다. 

만약 arguments를 사용하고 싶다면 rest parameter(나머지 매개변수)를 사용하자.



const printText = (...rest) => console.log(rest);
printText("Hello", "World!"); //["Hello", "World!"]



그리고 일반 함수에서 this 바인딩 때문에 버그가 발생하는 경우를 살펴보자.


window["resultValue"] = 1
const otherObj = {
resultValue: 1,
increase: function(){
console.log(this);
this.resultValue++;
},
};
otherObj.increase();
console.log(otherObj.resultValue); // 2
const otherIncrease = otherObj.increase;
otherIncrease();
console.log(otherObj.resultValue); // 2 변하지 않음
console.log(resultValue) // 2


otherObj 오브젝트의 increase 함수는 일반 함수로 정의하였다. 

increase 함수의 this는 자신을 정의한 otherObj 오브젝트를 가리킨다.

하지만 otherIncrease 함수의 this는 자신을 정의한 오브젝트 즉, 브라우저 환경에서 window 객체가 된다.



#4 Constructor (생성자) 함수 내부의 화살표 함수의 this


javascript 의 모든 개체( Object.create(null)로 만든 개체 제외 )에는 생성자 함수가 있습니다.


function Tree(name) {
this.name = name
}
let theTree = new Tree('Redwood')
console.log('theTree.constructor is ' + theTree.constructor)


이 생성자 함수 내부에서 화살표 함수에서 this를 사용해 봅시다.


function Calculator() {
this.value = 1
this.increase = () => this.value++;
}
const obj = new Calculator();
obj.increase();
console.log(obj.value); // 2
const increaseFn = obj.increase;
increaseFn();
console.log(obj.value); // 3

화살표 함수의 this는 new Calculator()로 생성된 개체가 된다.


반면 일반 함수로 정의하면

    
function Calculator() {
this.value = 1
this.increase = function (){
this.value++;
}
}
const obj = new Calculator();
obj.increase();
console.log(obj.value); // 2
const increaseFn = obj.increase;
increaseFn();
console.log(obj.value); // 2

앞서 살펴본 일반 함수의 this 정의와 같이

브라우저 환경이라면 increaseFn 함수를 정의한 window 객체가 this가 될 것이다.



#5 SetInterval 함수 사용 시 this 문제



다음의 1초마다 this.value를 증가시키는 코드에서 this가 어떤 객체를 참조하는지 생각해보자.


function IncreaseFn() {
this.value = 1;
setInterval(function increase(){
this.value++;
}, 1000);
}
const obj = new IncreaseFn();

// 몇 초뒤
console.log(obj.value); // 1

setInterval 함수의 인자인 increase 함수는 new IncreaseFn() 시점에 정의되면서

이때 this는 브라우저 환경에서 window 객체가 된다.


ES5에서는 편법으로 이 문제를 해결하였습니다.


function IncreaseFn() {
this.value = 1;
var $this = this;
setInterval(function increase(){
$this.value++;
}, 1000);
}
const obj = new IncreaseFn();

// 몇 초뒤
console.log(obj.value); // value 변경 됨

바로 Closure(클로저)를 이용해서 미리 저장해둔 $this 변수를 통해 this 객체에 접근한다.


잠시 Closure(클로저)에 대해서 알아봅시다.

클로저는 javascript에서 내부 함수가 외부 함수의 scope( 영역 )에 접근할 수 있는 기능입니다.

함수가 생성될 때마다 클로저가 생성됩니다.

클로저가 접근할 있는 변수는 함수를 감싸고 있는 외부 상위 함수들의 매개변수와 내부 변수들입니다.


const suffix = " -log.txt";     // 전역변수
function makeLogFn(prefix) {    // 외부함수
return function log(text){ // 내부함수
return prefix + text + suffix;
}
}
const infoLog = makeLogFn("INFO : ");
console.log(infoLog("somthing"));    // 1번
// INFO : somthing -log.txt
const errorLog = makeLogFn("ERROR : ");
console.log(errorLog("somthing"));   // 2번
// ERROR : somthing -log.txt
console.log(infoLog("somthing"));    // 3번
// INFO : somthing -log.txt

log 함수는 외부 함수의 매개변수에 접근할 수 있다.

1번에서 infoLog 함수가 생성된 이후에도 생성 당시 매개변수 값을 참조할 수 있다.

2번에서는 다른 매개변수로 함수가 생성되었음을 할 수 있다.

3번에서는 2번에서 errorLog 함수 생성 시 infoLog 함수에 영향을 주지 않는 것을 확인할 수 있다.

따라서 Log 함수 별로 각각의 클로저 환경이 생성된 것을 확인할 수 있다.


이를 화살표 함수를 이용해 편법을 사용하지 않고도 원하는 기능을 구현할 수 있습니다.


function IncreaseFn() {
this.value = 1;
setInterval(() => {
this.value++;
}, 1000);
}
const obj = new IncreaseFn();

// 몇 초뒤
console.log(obj.value); // value 변경 됨

위에 예에서 화살표 함수에는 자기 자신의 this는 없습니다.

이 화살표 함수를 둘러싼 scope(범위)가 this가 되는 것입니다.

화살표 함수는 일반 변수 참조 규칙을 따릅니다. 

그래서 this 찾기 위해 화살표 함수의 가까운 scope를 참조합니다.


화살표 함수는 화살표 함수가 정의된 scope를 기반으로 this를 생성합니다.

그래서 화살표 함수는 각기 다른 scope에서 실행될 수 있도록 설계 된 call, apply, bind 메서드에 적합하지 않습니다.


일반적인 예제입니다.

// 간단한 Object 생성
var obj = {
num: 100
}

// window 객체에도 num을 생성 합니다.
// 사용되지 않는 다는것을 증명하기 위해서입니다.
window.num = 2020;

// 일반 함수에서의 this
var add = function (a, b, c) {
return this.num + a + b + c;
}

// call
var result = add.call(obj, 1, 2, 3) // obj scope(범위) 생성
console.log(result) // 106

// apply
const arr = [1, 2, 3]
var result = add.apply(obj, arr) // obj scope(범위) 생성
console.log(result) // result 106

// bind
var result = add.bind(obj) // obj scope(범위) 생성
console.log(result(1, 2, 3)) // 106


다음은 window(global) 내에서 add 화살표 함수가 생성되는 것이라고 가정하에 어떤 결과가 나오는지 알아 봅시다.


// 간단한 Object 생성
var obj = {
num: 100
}

// window 객체에도 num을 생성 합니다.
// 이것이 어떻게 사용되는지를 확인하기 위해서 생성
window.num = 2020;

// Arrow Function
var add = (a, b, c) => this.num + a + b + c;

// call
console.log(add.call(obj, 1, 2, 3)) // 2026

// apply
const arr = [1, 2, 3]
console.log(add.apply(obj, arr)) // 2026

// bind
const bound = add.bind(obj)
console.log(bound(1, 2, 3)) // 2026

이처럼 화살표 함수 사용의 최대 장점은 

일반적으로 클로저 같은 기능, call, apply 또는 bind 기능이 꼭 필요한 DOM-level 메서드 ( setTimeout, setInterval, addEventListener)에 사용 해 적절한 scope(범위) 에서 함수가 실행 되도록 하기 위한 것입니다.


블로그 이미지

steadily

,


ES6+ 향상된 함수 기능 (1) - 매개변수


ES6에서 함수의 기능을 온전하게 완성했다고 볼 수 있다.

 - 매개변수에 기본값을 줄 수 있게 됨.

 - 나머지 매개변수를 통해 가변 길이 매개변수를 좀 더 명시적으로 표현할 수 있음.

 - Named parameter(명명된 매개변수)를 통해서 함수를 호출하는 코드의 가독성이 훨씬 좋아졌다.

 - Arrow function(화살표 함수)가 추가되면서 함수 코드가 간결해졌고, this 바인딩에 대한 고민을 덜 수 있게 되었다.


1.  매개변수에 추가된 기능.


#1 매개변수 기본값


ES6부터 함수 매개변수에 기본값을 줄 수 있다.


function printLog( a = 1 ) {
console.log({ a });
}
printLog(); // { a: 1 };



또한 객체 분해 할당처럼 기본값으로 함수 호출을 넣을 수 있고, 기본값이 필요한 경우에만 함수가 호출된다.


function getDefault() {
return 'None';
}
function printText(str = getDefault()) {
console.log({ str });
}
printText(); // { str: 'None'}



undefined가 입력된 경우에만 기본값 함수가 호출된다는 특징을 이용하면 매개변수에서 필숫값을 표현할 수 있다.


function required() {
throw new Error('No parameter');
}
function printText(str = required()){
console.log({ str });
}
printText('Hello'); // { str: 'Hello' }
printText(); // 에러 발생: No parameter


#2 Rest parameter (나머지 매개변수)


함수에 입력된 인수 중에서 정의된 매개변수 개수만큼을 제외한 나머지를 배열로 만들어 준다.

이는 변수가 가변적일 때 매우 유용하다.


function printText(str1, ...rest){
console.log({ str1, rest });
}
printText('A','B','O'); //{str1:'A', rest:['B','O']}

첫 번째 인자를 제외한 나머지를 rest 변수에 할당한다.


ES5에서는 arguments 키워드가 비슷한 역할을 한다.


function printText(str) {
const rest = Array.from(arguments).slice(1);
console.log({str, rest});
}
printText('a','b',1, 2);
// { str: 'a', rest: ['b',1,2] }

arguments는 명시적으로 드러나지 않아 가독성이 좋지 않다. 

그리고 arguments는 배열이 아니여서 배열처럼 사용하기 위해서는 배열로 변환해야한다.

Rest parameter ( 나머지 매개변수)를 사용하는게 낫다.


#3 Named parameter (명명된 매개변수)


명명된 매개변수는 객체 분해 할당을 이용해서 구현할 수 있다. 

함수 호출 시 매개변수의 이름과 값을 동시에 적을 수 있으므로 가독성이 높다.


const numbers = [1,2,3,4,5,6,7,8];
// 1번 함수
function getValues1(numbers,greaterThan,lessThan){
return numbers.filter((x) => x<lessThan&&x>greaterThan);
}
getValues(numbers, 2, 7); // 1
getValues(numbers, null, 7); // 2

// 2번 함수
function getValues2({ numbers, greaterThan = 0,lessThan =10}) {
return numbers.filter((x) => x<lessThan&&x>greaterThan);
}

getValues2({numbers, greaterThan:2, lessThan:7}); // 3
getValues2({numbers, lessThan:7}); // 4
getValues2({numbers, greaterThan:2}); // 5

1번 함수는 매개변수의 순서를 지켜야하는 함수이다. 

1번 실행에서는 2와 7이 무엇을 의미하는지 파악하기 어렵다.

2번 실행에서는 파라미터의 순서와 역할을 정확히 파악하고 필요없는 파리미터를 null로 채웠다.


반면 2번 함수는 Object 를 사용해 파라미터를 편하게 받을수 있게 하였다.

기본값도 할당이 가능하다. 객체 분해 할당 기능이 적용된다.

3번 실행 처럼 매개변수 이름을 노출 시켜 가독성을 높여준다.

4,5번 실행과 같이 Optional parameter(선택적 매개변수) 활용도를 높여준다.


여기서 함수를 호출할 떄마다 객체가 생성되기 때문에 비효율적일 것이라고 생각할 수 있다.

하지만 javascript 엔진이 최적화를 통해 새로운 객체를 생성하지 않는다고 한다. 안심하고 사용할 수 있다.


Name parameter 는 패턴이라고 할수 있다. 

유용한 예를 하나 살펴보자.


function apiRequest({
endpoint,
method = 'GET',
getParams = {},
headers = ['Content-Type: text-plain'],
callback = () => {},
timeout = 0,
authRequest = true,
} = {}) {
//...
console.log(arguments[0]);
return new Promise((resolve, reject) => {
resolve("resolve");
});
}

apiRequest({
endpoint: 'products',
getParams: { category: 3 },
})
// {endpoint: "products", getParams: { category: 3 }}


외에도 apiRequest 함수의 특수 버전을 만들 수 있습니다. 

아래와 같이 권한이 필요한 authApiRequest를 만들어 보자.


function authApiRequest (params) {
const token = 'whatever';
return new Promise((resolve, reject) => {
apiRequest({
...params,
headers: params.headers,
Authentication: token
})
.then(resolve)
.catch(reject)
});
}
// 실행 예제
authApiRequest({
endpoint: 'products',
getParams: { category: 3 },
});


또는 postRequest


function postRequest (params) {
return new Promise((resolve, reject) => {
apiRequest({...params, method: 'POST'})
.then(resolve)
.catch(reject)
});
}
// 실행 예제
postRequest({
endpoint: 'products',
getParams: { category: 3 },
});


똑같은 Named parameter 패턴으로 여러 변수들을 반환하는 함수를 만들어 봅시다.


function apiRequest({
endpoint,
method = 'GET',
getParams = {},
headers = ['Content-Type: text-plain'],
callback = () => {},
timeout = 0,
authRequest = true,
} = {}) {
//...
console.log(arguments[0]);
var response, error, loading
response = error = loading = null
//some amazing code...
return {
response,
error,
loading,
}
}

var { response, error, loading } = apiRequest({ endpoint: 'products' });

이런 식으로 함수의 응답을 구조화하여 다시 전후 관계와 의도를 제공 할 수 있습니다.


이것은 효과적으로 "함수에서 둘 이상의 값을 반환"하는 좋은 방법입니다. 

여러분들은 이 함수가 Object를 반환하고 있지만 또 다른 의미를 이미 알고있습니다.

바로 React Hooks 처럼 배열을 사용하여 값을 저장하고 반환 할 수 있습니다.



import React, { useState } from 'react';

function Example() {
// Declare a new state variable, which we'll call "count"
const [count, setCount] = useState(0);

return (
<div>
<p>You clicked {count} times</p>
<button onClick={() => setCount(count + 1)}>
Click me
</button>
</div>
);
}


블로그 이미지

steadily

,

ES6+ 향상된 Object, Array (2)


2.  간편하게 객체와 배열 속성값 가져오기.


#1 Spread operator (전개 연산자)


객체의 모든 속성을 꺼내어 나열하여 사용할 때 사용하는 문법이다.


Math.max(2, 5, 10); // 1
const numArr = [1, 2, 5, 6, 9];
Math.max(...numArr); // 2

1번의 방식은 한번 작성하고 나면 동적으로 변경할 수 없다.

하지만 2번에서는 전개 연산자를 사용하여 얼마든지 동적으로 변경된 객체를 매개변수로 전달할 수 있다.


이는 객체나 배열을 복사할 때도 유용하다.


const array1 = [1,2,4];
const object1 = { gender: 'Male', name: 'Peter'};
// 원본 객체를 전개하여 새로운 객체 생성
const array2 = [...array1];
const object2 = { ...object1};
// 속성을 수정하여도 원본 객체에 영향을 주지 않는다.
array2.push(9);
object2.gender = 'Female';



* 배열 = 전개 연산자를 사용해도 그 순서는 유지된다.

console.log( [1, 2, ...[3,4,5], 6] ); // [1,2,3,4,5,6]
new Date( ...[2020,10,12] );
// Thu Nov 12 2020 00:00:00 GMT+0900 (Korean Standard Time)

Date 함수처럼 정의된 매개변수를 순서대로 입력해야 할 때 유용하게 사용할 수 있다.


전개 연산자를 사용하여 서로 다른 두 배열 또는 두 객체를 쉽게 합칠 수 있다.


const object1 = { gender: 'Male', name: 'Peter'};
const object2 = { age: 21 };
const object3 = { ...object1, ...object2};
console.log(object3); // {gender: "male", name: "peter", age: 21}


이때 객체 리터럴에서 속성명이 중복된다면...

ES5까지는 에러가 발생했으나 ES6부터 허용된다.


const object1 = { a: 1, a: 3, b: 4, c: 5};
// { a: 3, b: 4, c: 5 }
const object2 = { ...object1, c: 7 };
// { a: 3, b: 4, c: 7 }

중복 시 최종 결과는 마지막 속성 명의 값이 된다.

* 전개 연산자를 활용하면 원본 객체에 영향을 주지 않고, 특정 속성값 (c: 7)을 변경하고 새로운 객체를 만들어 낼 수 있다.

이는 수정 불가능 변수를 관리할 때 유용하게 사용된다.



#2 Array destructuring assignment(배열 분해 할당)


배열의 여러 속성값을 변수로 분해하여 쉽게 할당할 수 있는 문법이다.

배열 분해 할당 예제를 살펴보자.


const arr = [1, 2];
const [a, b] = arr; // 배열의 속성값을 순서대로 할당한다.
console.log(a); // 1
console.log(b); // 2


다음과 같이 이미 정의된 변수에도 할당이 가능하다.


let a, b;
[a, b] = [1, 2];


초기 default 값 설정도 가능하다.

const arr = [99];
const [a = 1, b = 2] = arr;
console.log(a); // 99
console.log(b); // 2


배열 분해 할당을 통해 두 변수의 값을 쉽게 변경 교환할 수 있다.


let a = 10;
let b = 20;
[a, b] = [b, a];
console.log(a); // 20
console.log(b); // 10


배열 분해 할당에서 배열 속성의 순서를 쉼표를 입력해 설정할 수 있다.

const arr = [10, 20, 30];
const [a, , c] = arr;
console.log(a); // 10
console.log(b); // 30


추출한 속성 개수만큼을 제외한 나머지로 새로운 배열을 생성할 수 있다.


const arr = [10, 20, 30];
const [first, ...rest1] = arr;
console.log(rest1); // [20, 30]
const [a, b, c, ...rest2] = arr;
console.log(rest2); // []

위와 같이 배열 분해 할당 시 마지막에 ... 을 통해 변수에 나머지 모든 속성값으로 새로운 배열을 만든다.

또한 나머지가 없으면 빈 배열을 생성한다.



#2 Object destructuring assignment(객체 분해 할당)


객체의 여러 속성값을 변수로 분해하여 쉽게 할당할 수 있는 문법이다.


const obj = { gender: 'Male', name: 'Peter' };
const { gender, name } = obj;
console.log(gender); // male
console.log(name); // peter

객체는 속성명을 그대로 가져와 할당하기 때문에 순서는 중요하지 않다.


따라서 배열 분해 할당에서는 변수명을 변경할 수 있었지만 객체 분해 할당에서는 그대로 사용해야 한다.


const obj = { gender: 'Male', name: 'Peter' };
const { gender, name } = obj; // 1
const { name, gender } = obj; // 2
const { a, b } = obj; // 3

1, 2의 결과는 동일하다. 3은 존재하지 않은 속성명을 사용하여 undefined가 할당 된다.


새로운 변수명에 할당도 가능하다.


const obj = { gender: 'Male', name: 'peter' };
const { gender: sex, name } = obj;
console.log(sex); // 'male'
console.log(gender) // 참조 에러

obj의 속성 gendersex 변수에 할당된다. gender라는 변수는 생기지 않고 gender의 값이 sex 변수에 할당된다.


배열 분해 할당처럼 객체 분해 할당에서도 기본값을 정의 할 수 있다.


const obj = { gender: undefined, name: null, age: 21 };
const { gender = 'none', name = 'none', age = 0 } = obj;
console.log(gender); // none 1
console.log(name); // null 2
console.log(age) // 21

1의 genderundefined이기 때문에 defaultnone을 할당한다.

2의 namenull이기 때문에 null 값을 할당한다. 명심하자.


변수명 사용자 정의와 default(기본값) 설정을 동시에 해보자.


const obj = { gender: undefined, name: 'Peter'};
const { gender: sex = 'none', name} = obj;
console.log(sex); // 'none'


또한 기본값으로 함수의 return 값을 넣을 수 있다.

function getDefaultText() {
console.log('getDefaultText');
return 'none';
}
const obj1 = { gender: undefined, name: 'Peter'};
const { gender = getDefaultText(), name} = obj1;
// 'getDefaultText' 출력

const obj2 = { address: 'Seoul', empNo: 00001 };
const { address = getDefaultText(), empNo} = obj2;
// 'getDefaultText' 출력 되지않음

당연한 결과지만 default 값을 지정할 경우에만 함수가 호출된다.


객체 분해 할당 시 할당되지 않은 값들로 하나의 별도의 개체를 만들 수 있다.

const obj = {gender: 'Male', name: 'Peter', age: 24};
const { name, ...rest } = obj;
console.log(rest); // { gender: 'male', age: 24 }

배열 분해 할당과 비슷한 방식이다.


for of 문 사용 시 객체 분해 할당을 활용해 보자


const userList = [
{ gender: 'Male', name: 'Peter', age: 24},
{ gender: 'Female', name: 'Jane', age: 24},
]
for(const {gender, name} of userList) {
console.log(name + " : " + gender);
}



객체 속 객체도 분해 가능하다.

const obj = { name: 'Peter', friend: { name: 'Jane'} };
const {
name,
friend: { name: friendName },
} = obj;
console.log(name); // 'peter'
console.log(friendName); // 'Jane'
console.log(friend); // 참조 에러

객체 분해 할당을 통해 friendName이라는 변수만 생성된다.


분해 할당을 통해 변수 단위만 정의할 수 있는 것은 아니다. 패턴 단위로 분해 할당이 가능하다.


const [{ prop: a } = { prop: 111 }] = []; // 1
console.log(a); // 111
const [{ prop: b } = { prop: 111 }] = [{}]; // 2
console.log(b); // undefined

1은 배열에서 첫 번째 원소가 { prop: a }이며, 기본값을 { prop: 111 }로 정의했다. 객체 분해할 [ ]의 첫 번째 원소가 없으므로 기본값이 할당된다.

2에서는 객체 분해할 [{ }]의 첫 번째 원소가 {}이며 prop 속성명은 존재하지 않으므로 bundefined가 할당된다.


객체 분해 할당에서 계산된 속성명을 활용할 수 있다.


const idx = 1;
const { [`key${idx}`]: valOfIdx } = { key1: 111 };
console.log(valOfIdx); // 111

객체 분해 할당에서 계산된 속성명을 사용할 때에는 반드시 별칭을 입력해야 한다.


별칭은 단순히 변수명만 입력할 수 있는 것은 아니다.


const obj = {};
const arr = [];
({ a: obj.prop, b: arr[0]} = { a: 111, b: true });
console.log(obj); // { prop:111 }
console.log(arr); // [ true ]

이처럼 객체의 속성명 또는 배열의 첫 번째 원소에 값을 할당할 수 있다.

블로그 이미지

steadily

,

ES6+ 향상된 Object, Array (1)


1. 객체와 배열의 생성과 수정을 간편하게.


#1 Shorthand property names (단축 속성명)


Literal Code를 간편하게 작성


const name = 'peter';
const obj = {
gender: 'male',
name, // 이미 정의 된 변수면 변수명 입력 {name: 'peter'}
getName() { return this.name},
// 함수형은 function 키워드 생략 { getName : function(){....}}
}

비교를 통해 어떻게 개선 되었는지 알아보자.


// 기존 함수 정의
function createUser(name, gender) {
return { name: name, gender: gender};
}
// 개선된 방법
function createUser(name, gender) {
return { name, gender};
}

이렇게 단축 속성명을 사용하면 코드 작성도 간편하고 가독성도 좋아진다.


아래와 같이 디버깅 시 많이 개선된 점을 확인할 수 있다.


const name = 'peter';
const gender = 'male';
// 기존방식
console.log('name =' + name, ', gender =' + gender);
// ES6+
console.log({ name, gender }); // { name: 'peter', gender: 'male' }



#2 Computed property names (계산된 속성명)


더 편리하게 동적으로 속성명을 결정할 수 있게 되었다.

계산된 속성명을 사용한 코드와 그렇지 않은 코드를 비교해보자.


function createObj1( key, val ) {
const obj = {};
obj[key] = val;
return obj;
}
function createObj2( key, val ) {
return { [key]: val };
}

계산된 속성명을 사용하면 createObj2 함수처럼 간결하게 작성할 수 있다.


이 기능을 컴포넌트의 상탯값을 변경할 때 사용하면 유용하다.


class CntComponent extends React.Component {
state = {
cnt1: 0,
cnt2: 0,
cnt3: 0,
};
// ...
onClick = idx => {
const key = `cnt${idx}`;
const val = this.state[key];
this.setState({ [key]: val + 1 }); // 1
}
}

1번에서 복잡해질수 있는 코드를 계산된 속성명을 사용하여 간결하게 작성하였다.




블로그 이미지

steadily

,