JavaScript Codestates Koans!!!

코란은 이슬람 경전이다. 굉장히 비밀스럽게 유지되고 신자가 아닌자가 읽을 수 없다고 하지만. 역사를 좋아하는 나는 누군가 읽어서 짧게 요약한걸 본적이 있다. 성경과 비슷하다라는 느낌을 받았고, 이것저것 찾아본 결과 주관적 견해지만. 그 신이 그 신이었다. 일부 기독교인들에게는 굉장히 불경한 발언일지는 몰라도 나는 그렇게 생각했다. 그래서 뭔가의 코딩의 경전이가 생각하고 접근했는데 그게 아니라 Koans를 검색하니 정말 코안이라고 뜬다. 심지어 Kotlin 연습에 관련된게 Koans라고 뜨더라. 응 이거 찾을 시간에 공부나하자.


1. 별난(quirky) 저장소

123 - "1" === 122; //true ?????

위와같이 이해되지 않는 연산이 있다. 이부분을 따로 모아놓은 저장소도 있다고한다. 이런 부분은 올바른 코딩습관(strick equal 엄격한)으로 비교 연산을 명시하자.

2. const의 사용

const a = 'a';
...
const a = 'b'; // Error 재할당을 금지하는 상수선언

//배열
const arr = [];

arr = [1, 2]; // Error 재할당은 안된다.

//추가나 제거는 된다.
arr[0] = 1;
arr.pop();

//객체
const obj = {};

obj = {'0': 1}; // Error 재할당은 안된다.

obj['0'] = 1; // 추가
'0' in obj; //true;
delete obj['0']; // 삭제

3. 함수 선언과 표현

function declareFunction(){
    return '함수 선언식';
}
const expressedFunction = function () {
    return '함수 표현식';
};
// 자바스크립트 함수 호이스팅(hoisting)에 대해서 검색해 봅니다.
const funcContainer = { func: funcExpressed };
funcContainer.func(); //함수 표현식 반환

//이런 문법도 가능하다니?
func defaultParams(num = 10){
    return num + 10;
}
defaultParams(); // 20
defaultParams(80) // 100

3.1. 추천검색어

4. Arrow Function

function legacy(){
    return arguments;
}

const functionExample = () => {
    return arguments;
}

const functionExample1 = () => arguments;

const functionExample2 = ...params => params;

const additionFunctionExample = num1 => num2 => num1 + num2;

const closureFunction = additionFunctionExample(10); // typeof function
closureFunction(100);   //110

additionFunctionExample(100)(1_000);    //1100 typeof number

못써도 상관없지만, 알아보지 못하면 같이 일을 할 수 없다.

5. Primitive Data Type & Reference Data Type

컴퓨터와 메모리구조와 자바스크립트의 메모리 구조를 이해하면 당신은 이미 마스터

6.1. 원시 자료형은 값이 콜스택 / 참조 자료형은 값이 메모리 힙에 올라가고 콜스택에는 주소를 담은 값이 올라간다. 서로의 영역을 넘어서면 stack over flow / heap over flow

6.2. Codestates 자바스크립트 메모리 시각화(문제시 자삭)

출처 Codestates Koans

Object.keys([1, 2, 3, 4, 5]); //['0', '1', '2', '3', '4']

const nums = [1, 2, 3];

nums === [1, 2, 3]; //false

const nums1 = nums;

nums[0] = 0;

nums === nums1; //true

7. Array & Object

//배열==================================================
//얕은 복사
const arr = [1, 2, 3, 4];
const assignArr = arr;
assignArr.pop(); // [1, 2, 3]
assignArr.shift(); // [2, 3]
assignArr.push(99); //  [2, 3, 99]
assignArr.unshift(100); // [100, 2, 3, 99]
arr; // [100, 2, 3, 99] 변조됨

//깊은 복사
const arr1 = [1, 2, 3, 4];
const copyArr = arr1.slice(); //.slice(0) [1, 2, 3, 4]
copyArr[2] = 10; // [1, 2, 10, 4];
arr1; // [1, 2, 3, 4]
//slice() 메서드는 원본이 아닌 새로운 배열을 생성한 것이다.
//=======================================================

//=-*-=-*-=-*-=-*-=-*-=-*-=-*-=-*-=-*-=-*-=-*-=-*-=-*-=-*

//객체====================================================
const obj = {};
const keyAge = "age";
obj.name = "ty";
obj[keyAge] = 30;

obj; // { name: 'ty', age: 30 }
keyAge in obj; // true;
delete obj[keyAge];
keyAge in obj; // false;
obj; // { name: 'ty' };
const myProfile = {
  name: "ty",
  age: 30,
  getFull: function () {
    return `${this.name}(${this.age})`;
    //this는 상기에서는 객체를 가르킴.
  },
};

const urProfile = {
  name: "poe",
  age: 30,
  getFull: () => `${this.name}(${this.age})`,
  //자신의 this가 없다. super도 안먹는다.
  //화살표 함수에서는 this가 자신을 감싼 정적 범위(lexical context)
  //전역에서는 전역을 가킴
  //일반 변수 조회 규칙(normal variable lookup rules)을 따른다.
  //현재 범위에서 존재하지 않는 this를 찾을 때 화살표 함수
  //바로 바깥 범위에서 this를 찾는다.
};

myProfile.getFull(); //ty(30)
urProfile["getFull"](); //(undefined)

//얕은 복사
const shCopyObj = myProfile; //배열과 동일함.

//객체를 함수의 전달인자로 전달 시 reference가 전달된다.
const currentAge = (referObj) => (referObj.age = 37);
currentAge(shCopyObj);

myProfile; // { name: 'ty', age: 37, getFull: f()... }
//원본이 변조됨.

//깊은 복사
const dpCopyObj = Object.assign({}, urProfile);
currentAge(dpCopyObj);

urProfile; // { name: 'poe', age: 30, getFull: f()... }
//=======================================================

7.1. n중 배열과 n중 객체의 경우 깊은복사가 일어나더라도 reference를 가져간다.!!!!!!!!!!!!

7.2. 얕은복사(shallow copy)깊은복사(deep copy)

  • 얕은복사(shallow copy): “개체 의 얕은 복사본 은 속성이 복사본이 만들어진 원본 개체의 참조와 동일한 참조(동일한 기본 값을 가리킴)를 공유하는 복사본입니다. 결과적으로 소스나 복사본 중 하나를 변경하면 다른 개체도 변경될 수 있습니다. 따라서 의도하지 않은 소스나 복사본에 예상치 못한 변경이 발생할 수 있습니다. 이 동작 은 원본과 복사본이 완전히 독립적인 깊은 복사 의 동작과 대조됩니다.” …MDN
  • 깊은복사(deep copy): 개체 의 전체 복사본 은 속성이 복사본이 만들어진 원본 개체의 참조와 동일한 참조(동일한 기본 값을 가리킴)를 공유하지 않는 복사본입니다. 결과적으로 소스나 복사본을 변경할 때 다른 개체도 변경하지 않도록 할 수 있습니다. 즉, 의도하지 않은 소스나 복사본을 의도하지 않게 변경하지 않을 것입니다. 이 동작 은 소스나 복사본 중 하나를 변경하면 다른 개체도 변경될 수 있는 얕은 복사본 의 동작과 대조됩니다 (두 개체가 동일한 참조를 공유하기 때문에). …MDN

8. Spread Syntax

spread syntax는 나머지연산자라고 max는 표현했지만 정확히는 전개라고 하는게 맞다.

//새로운 배열로 합침.
const adds = ['Derosa', 'Fuji'];
const makers = ['Specialized', ...add, 'Giant'];
makes;  //['Specialized', 'Derosa', 'Fuji', 'Giant']

//빈배열 전달 시 전달안됨
const empties = [];
const arr = [0, ...empties, 1];
arr;    //[0, 1]

//배열을 concatenate 이어붙이기 가능.
const concatenates = [...makers, ...arr];
concatenates;   //['Specialized', 'Derosa', 'Fuji', 'Giant', 0, 1]

//객체 역시 합칠 수 있다. 겹치는건 덮어쓴다.
const person = {
    name: 'ty',
    age: 30,
}
const addon = {
    age: 37,
    addr: 'Hanamsi'
}
const merged = {...person, ...addon};

merged; //{name: 'ty', age: 37, addr: 'Hanamsi'}

//함수의 전달인자를 배열로 다룰 수 있다. 지정한 값을 넣지 않으면 undefined
const getOnlyOne = elementIndex0 => elementIndex0;
const one = getOnlyOne('one','two','three');
one;    //one 1,2번 인덱스는 달라고 명시하지 않음.

const getUndefined = (elementSomething, elementNothing) => elementNothing;
const none = getUndefined('anyValue');

none;   //undefined index[0]번만 넣었고, 함수자체에서 1번을 넣을 수없게 설계됨

//rest parameter사용
const getCategories = ...categories => categories;
const bikeCategories = getCategories('mtb', 'rode', 'fixed', 'minivelo');
bikeCategories; //['mtb', 'rode', 'fixed', 'minivelo']

//MDN arguments 객체 확인하세요 :D 배열이 아니다!!!!
const getPutEmptyParamsGetAllArgumentsObject(){
    //나는 분명 아무것도 넣지않는다.
    return arguments;   //지정된 arguments를 함수내에서만 쓴다.
}

const argsObj = getPutEmptyParamsGetAllArgumentsObject(1,2,3,4,5);
argsObj;   // [1,2,3,4,5]
Array.isArray(argsObj);    //false 배열아니다. 배열로 만드는건 MDN참조

Object.keys(argsObj);   //['0','1','2','3','4']
// 배열의 index가 문자열로 key
Object.values(args);    // [1,2,3,4,5]

//배열로 만들기 위해서는 정해진 함수가 필요하다.
const arrArgsObj = Array.from(argsObj);
Array.isArray(arrArgsObj);  //true 배열이 되었다.
//arguments객체로 만든 배열로보이는 뭔가는 배열이 아니다.

9. Destructuring

//배열을 순서대로 분해
const arr = [1,2,3,4];
const ['index0', 'index1'] = arr;
arr;    //[1,2]

//rest/spread syntax 적용이 가능 => posting Spread & Rest 확인

//할당하기 전 왼쪽에는 rest syntax 이후 쉼표 불가능
// const [i0, ...iMiddle, iLast] = someArray;

참조

Github:Denysdovhan/Quirky
MDN:JS/const
Google:JSGuide-const & let
MDN:JS/Hoisting
MDN:JS/Closure
MDN:JS/Shallow Copy
MDN:JS/Deep Copy
MDN:JS/this
SCOTCH:Copying Objects
Watcha:깊은복사 & 얕은복사
MDN:JS/Spread Syntax
MDN:JS/arguments
MDN:JS/Destructuring Assignment
Github:Codestates-seb/Koans Reference
JSKoreaInfo:Strict mode
JSKoreaInfo:Old var
Poiemaweb:ES6/호이스팅