[JS] #4 변수
spread
const list = [21, 22]; console.log([11, ...list, 12]); const obj = {key: 50}; console.log({...obj}); // [11,21,22,12] // {key: 50}
- Syntax: [...iterable]
- [...varName] 처럼 [ ]안에 점(.) 3개를 작성하고 이어서 이터러블 오브젝트를 작성합니다.
- 이터러블 오브젝트를 하나씩 전개합니다.
- {key: value}의 Object가 이터러블 오브젝트는 아니지만 전개가 가능합니다.
Array spread
const one = [21, 22]; const two = [31, 32]; const result = [11, ...one, 12, ...two]; console.log(result); consoel.log(result.length); // [11,21,22,12,31,32] // 6
- spread 대상 배열을 작성한 위치에 엘리먼트 단위로 분리 및 전개합니다.
const one = [21, 22]; const result = [11, 12, ...one]; console.log(result); console.log(result.length); // [11, 12, 21, 22] // 4
- 값이 대체되지 않고 전개됩니다.
⇒ 만약, 값이 대체되는 것이면 [11, 12, [21, 22]]로 이차원 배열이 되고, length는 3이 되게 됩니다.
push(...spread)
let result = [21, 22]; const five = [51, 52]; result.push(...five); console.log(result); result.push(..."abc"); console.log(result); // [21, 22, 51, 52] // [21, 22, 51, 52, a, b, c]
- push( ) 파라미터에 spread 대상을 작성할 수 있습니다.
- 배열 끝에 대상을 분리하여 첨부합니다.
String spread
const target = "ABC"; console.log([...target]); // [A, B, C]
- spread 대상 문자열을 작성한 위치에 문자 단위로 전개합니다.
⇒ target의 ABC를 문자 단위로 분리하여 전개합니다.
Object spread
const one = {key1: 11, key2: 22}; const result = {key3: 33, ...one}; console.log(result); // {key3: 33, key1: 11, key2: 22}
- spread 대상 Object를 작성한 위치에 프로퍼티 단위로 전개합니다.
⇒ ...one 은 one오브젝트의 프로퍼티를 전개합니다.
const one = {key1: 11, key2: 22}; const result = {key1: 33, ...one}; console.log(result); // {key1: 11, key2: 22} // const check = [...one]; --- error
- 프로퍼티의 이름이 같을경우 값을 대체합니다.
⇒ one의 key1과 result의 key1은 프로퍼티 이름이 같기에 뒤에 작성한 one의 프로퍼티 내용으로 대체됩니다. 그래서 key1은 33이 아닌 11이 출력됩니다.
⇒ const check = [...one]; one은 빌트인 오브젝트이기에 이터러블 오브젝트가 아니므로 대괄호 형태로 작성하면 에러가 발생합니다.
Rest 파라미터
function spread
호출하는 함수의 파라미터에 spread대상을 작성합니다.
function add(one, two, three) { console.log(one + two + three); }; const values = [10, 20, 30]; add(...values); // 60
- 처리 순서 및 방법
- 함수가 호출되면 우선, 파라미터 배열을 엘리먼트 단위로 전개
- add(...values) → add(10, 20, 30); 이와같이 전개
- 전개한 순서대로 파라미터 값으로 넘겨줍니다.
- 호출받는 함수의 파라미터에 순서대로 매핑됩니다.
rest 파라미터
분리하여 받은 파라미터를 배열로 결합합니다.
spread: 분리, rest: 결합
syntax: function(param, paramN, ...name)
function point(...param) { console.log(param); console.log(Array.isArray(param)); } const values = [10, 20, 30]; point(...values); // [10, 20, 30] // true
-
작성 방법
- 호출받는 함수의 파라미터에 ...에 이어서 파라미터 이름 작성을 합니다.
- 호출한 함수에서 보낸 순서로 매핑합니다.
⇒ point(...values) → point(10, 20, 30)이 되어 호출합니다.
⇒ rest 파라미터로 다시 결합하여 param = [10, 20, 30]이 됩니다.
function point(ten, ...rest) { console.log(ten); console.log(rest); }; const values = [10, 20, 30]; point(...values); // 10 // [20, 30]
- 파라미터와 Rest파라미터를 혼합 사용할 수 있습니다.
⇒ point(...values) → point(10, 20, 30)이 되어 호출합니다.
⇒ point에서는 첫번째 파라미터인 10을 ten에 할당합니다.
⇒ 나머지 20, 30을 ...rest 파라미터로 결합하여 최종적으로는 point(10, [20,30])으로 받게 됩니다.
Array-like
Object 타입이지만 배열처럼 이터러블 가능한 오브젝트입니다. for()문으로 전개할 수 있습니다.
const values = {0: "가",1:"나", 2:"다", length: 3}; for(let k = 0; k< values.length; k++){ console.log(values[k]); };
-
작성 방법
- 프로퍼티key 값을 0부터 1씩 증가하며 프로퍼티 값 작성
- length에 전체 프로퍼티 수 작성
⇒ length 프로퍼티는 전개되지 않습니다(하면 안됩니다)
⇒ for~in문으로 전개할 경우 length 프로퍼티도 전개됩니다.
rest와 arguments의 차이점
- Argument 오브젝트
- 파라미터 작성에 관계없이 전체를 설정합니다.
- Array-like 형태 : Array 메소드를 사용할 수 없습니다.
- __proto__가 Object 입니다.
- rest 파라미터
- 매핑되지 않은 나머지 파라미터만 설정합니다.
- Array 오브젝트 형태 : Array 메소드를 사용할 수 있습니다.
- __proto__가 Array
분할할당(Destructuring)
let one, two, three; const list = [1, 2, 3]; [one, two, three] = list; console.log(one); console.log(two); console.log(three); console.log(list); // 1 // 2 // 3 // [1,2,3]
사전적 의미로는 구조를 파괴한다는 의미가 있습니다. 하지만, 코드를 보면 원본 데이터가 파괴된다기보다는 구조분해 후 특정요소 pick을 한다는게 더 맞는 의미입니다.
즉, 파괴보다는 분할/분리에 더 가깝다고 볼 수 있고, "분할 할당"이라고 할 수 있습니다.
Array분할 할당
배열의 엘리먼트를 분할하여 할당할 수 있습니다.
-
인덱스에 해당하는 변수에 할당
⇒ 왼쪽의 인덱스에 해당하는 오른쪽 배열의 값을 할당합니다. one에 1, two에 2, three에 3이 할당됩니다.let one, two, three; [one, two, three] = [1, 2, 3]; console.log(one); console.log(two); console.log(three); // 1 // 2 // 3
-
할당받을 변수 수가 적은 경우
⇒ 왼쪽에 할당받을 변수가 분할 할당할 값보다 적은 경우 왼쪽 인덱스에 맞추어 값을 할당합니다. 그렇기에 3은 할당되지 않습니다.let one, two; [one, two] = [1, 2, 3]; console.log(one); console.log(two); // 1 // 2
-
할당받을 변수 수가 많은 경우
⇒ 왼쪽의 할당받을 변수가 3개이고 분할 할당할 값이 2개라면 왼쪽에 값을 할당할 수 없는 변수에는 undefined가 설정됩니다.let one, two, three; [one, two, three] = [1, 2]; console.log(two); console.log(three); // 2 // undefined
-
배열 차원에 맞추어 분할 할당을 합니다.
⇒ [three, four]와 [3,4]가 배열이고 배열 차원도 변환됩니다.let one, two, three, four; [one, two, [three, four]] = [1,2,[3,4]]; console.log([one, two, three, four]); // [1,2,3,4]
-
매치되는 인덱스에 변수가 없으면 값을 할당하지 않습니다.
⇒ [one, , , four] 형태에서 콤마로 구분하고 변수를 작성하지 않을 경우 인덱스를 건너 띄어 할당합니다.let one, two, three, four; [one, , , four] = [1,2,3,4]; console.log([one, two, three, four]); // [1, undefined, undefined, 4]
spread와 병행 사용
-
나머지를 전부 할당
let one, rest; [one, ...rest] = [1,2,3,4]; console.log(one); console.log(rest); // 1 // [2,3,4]
-
인덱스를 반영한 나머지 할당
let one, three, rest; [one, ,three ...rest] = [1,2,3,4, 5]; console.log(three); console.log(rest); // 3 // [4, 5]
Object 분할 할당
Object의 프로퍼티를 분할하여 할당합니다.
-
프로퍼티 이름이 같은 프로퍼티에 값을 할당합니다.
const {one, two} = {one: 10, two: 20}; console.log(one); console.log(two); // 10 // 20
-
프로퍼티 이름을 별도로 작성
⇒ 이처럼 프로퍼티 명을 위에 별도로 작성을 한 경우에 분할 할당을 하기위해서는 소괄호안에 작성을 하여 평가해야합니다.let one, two ({one, two} = {one: 10, two: 20}); console.log(one); console.log(two); // 10 // 20
-
프로퍼티 값 위치에 변수 이름 작성
⇒ 이름을 별도로 선언했기에 소괄호안에 작성합니다.
one의 프로퍼티 값 5를 five에 할당하고, six도 마찬가지로 two의 프로퍼티 값인 6을 할당합니다.
이때 one을 출력하려하면 ReferenceError가 발생합니다.(단지 분류의 기능 수행)let five, six; ({one: five, two: six} = {one: 5, two: 6}); console.log(five); console.log(six); // console.log(one); --- ReferenceError // 5 // 6
-
Object구조에 맞춰 값 할당
⇒ 왼쪽의 할당받는 변수에서 plus: {two, three}에서 plus는 구조(경로)를 만들기 위해 존재하며 구조가 다르면 실행할 때 에러가 발생하기에 작성합니다. 그렇기에 plus는 실제로 존재하지 않습니다.const {one, plus: {two, three}} = {one: 10, plus:{two:20, three:30}}; console.log(one); console.log(two); console.log(three); // 10 // 20 // 30
-
나머지를 Object로 할당
const {one, ...rest} = {one: 10, two: 20, three:30}; console.log(rest); // {two: 20, three:30}
파라미터 분할 할당
-
호출하는 함수에서 Object형태로 넘겨준 파라미터 값을 호출받는 함수의 파라미터에 맞추어 할당합니다.
function add({one, two}) { console.log(one + two); } add({one: 10, two: 20}); // 30
⇒ 호출하는 함수에서 넘겨준 one과 two가 담긴 오브젝트를 호출받는 함수의 프로퍼티 이름에 맞춰 분할 할당합니다.
- Object구조에 맞춰 값을 할당합니다.
function add({one, plus:{two}}) { console.log(one + two); } add({one: 10, plus:{two: 20}}); // 30
Object 오퍼레이션
-
같은 프로퍼티 이름 사용
const value = {book: 10, book: 20}; console.log(value); // 20
- {book: 10, book: 20}에서 프로퍼티 이름(book)이 같습니다.
- ES5 strict 모드에서 프로퍼티 이름이 같으면 에러가 발생합니다.
- ES6에서는 strict 모드에 관계 없이 에러가 발생하지 않고 뒤에 작성한 프로퍼티 값으로 대체됩니다.
-
Shorthand property names
const one = 10, two = 20; const values = {one, two}; console.log(values); // {one: 10, two: 20}
- one과 two변수에 값을 작성 후 {one, two} 형태로 value에 할당합니다.
- 그렇게 되면 one, two는 프로퍼티 이름이되고 10, 20이 프로퍼티 값으로 할당이 됩니다.
- 이것(Shorthand property names)은 MDN에 작성된 것으로 스펙에 정의된 것은 아닙니다.
프로퍼티 이름 조합
-
문자열을 프로퍼티 이름으로 사용
const value = { ["one" + "two"]: 12 }; console.log(value.onetwo); // 12
⇒ [ ]안에 문자열로 이름을 작성하면 그 문자열이 프로퍼티 이름이 되는데 우측 코드에서 one + two로 문자열 결합이 되어 onetwo가 프로퍼티 이름으로 사용됩니다.
-
변수값을 프로퍼티 이름으로 사용
const item = "world"; const sports = { [item]: 100, [item + " Cup"]: "월드컵", [item + "Sports"]: function() { return "스포츠"; } }; console.log(sports[item]); // 100 console.log(sports[item + " Cup"]); //월드컵 console.log(sports[item + "Sports"]());// 스포츠 // 100 // 월드컵 // 스포츠
⇒ 변수값을 프로퍼티 이름으로 사용합니다.
⇒ 변수값을 문자열 결합하여 사용할 수도 있습니다.
⇒ 프로퍼티 이름에 공백도 넣을 수 있습니다.
⇒ 함수로 호출할 수도 있습니다. -
분할 할당을 조합한 형태
const item = "book"; const result = {[item]: title} = {book: "책"}; console.log(result);
⇒ 변수값을 프로퍼티 이름으로 사용하고 분할 할당하는 형태입니다.
⇒ {[item]: title}은 {book: title} 형태가 됩니다.
⇒ {book: title} = {book: "책"}이 되어 result는 {book: "책"}이 됩니다.
default value
값을 할당하지 않으면 사전에 정의된 값(default value)을 할당하는 것입니다.
-
할당할 값이 없으면 디폴트 값을 할당합니다.
const [one, two, five = 50] = [10, 20]; console.log(five); // 50
- one에는 10을, two에는 20을 분할 할당합니다.
- 이때 five에는 할당할 값이 없지만, five = 50이기에 50을 할당합니다.
- 이것을 default value라 합니다.
-
할당할 값이 있으면 디폴트 값을 무시합니다.
const [one, two, five = 50] = [10, 20, 70]; console.log(five); // 70
⇒ 왼쪽과 오른쪽 모두 값이 3개로 할당 값도 할당 받을 변수도 맞기에 five는 50이 아닌 우측에서 70을 할당받습니다.
-
Object는 프로퍼티 이름으로 체크합니다.
const {one, two = 20} = {one: 10}; console.log(two); // 20
⇒ 우측의 one값인 10을 좌측의 one 프로퍼티 값으로 분할할당합니다. two에는 할당할 값이 없으며 기본값인 20을 할당합니다.
-
디폴트 값 적용 순서(좌 → 우)
const [one, two = one + 20, five = two + 50] = [10]; console.log(two); console.log(five); // 30 // 80
- 우측의 one값인 10을 좌측의 one프로퍼티 값으로 분할 할당합니다.
- 이 후 우측 two와 five는 값이 없기에 디폴트 값을 할당합니다.
- two는 one이 10으로 할당되어 two + one + 20에서
10+20이 되어 30이되고 - five도 같은 방법으로 30 + 50이 되어 80이 디폴트 값으로 할당됩니다.
함수의 파라미터에 디폴트 값 적용
-
넘겨받은 파라미터 값이 없으면 디폴트 값을 할당합니다
const add = (ten, two = 20) => ten + two; const result = add(10); console.log(result); // 30
- add를 호출하는 시점에서 10을 넘겨주기에 ten에는 10이 할당됩니다.
- two는 할당된 값이 없기에 undefined가 할당되야하나, 기본값이 20이 있어 20이 할당됩니다.
-
넘겨받은 파라미터 값이 있으면 디폴트 값을 무시합니다.
const add = (ten, two = 20) => ten + two; const result = add(10, 50); console.log(result); // 60
⇒ add(10, 50)으로 두 번쨰 파라미터도 작성을 해주게 되면 호출받은 함수의 파라미터부분에서도 디폴트 값을 적용하지 않습니다
-
호출한 함수의 파라미터 값이 undefined일 때
const point = () => 20; const add (one, two = point()) => one + two); const result = add(10, undefined); console.log(result); // 30
- add(10, undefined)에서 두 번째 파라미터 값이 undefined이지만 파라미터 값을 넘겨주지 않은 것과 같습니다.
- point()함수를 호출해 반환된 값(20)을 디폴트 값으로 사용합니다.
Author And Source
이 문제에 관하여([JS] #4 변수), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://velog.io/@simoniful/JS-4-변수저자 귀속: 원작자 정보가 원작자 URL에 포함되어 있으며 저작권은 원작자 소유입니다.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)