koans 21.03.13


for-if-continue vs for-if-break

  • for-if-continue : for문 내에서 continue는 현재 반복에서 현재 명령문의 실행을 종료하고 반복문의 처음으로 돌아가여 루프문의 다음 코드를 실행. (while 루프일 경우 다시 조건으로 점프, for 루프일 경우 업데이트 표현식으로 점프)

ex code

let text = '';

for (let i = 0; i < 10; i++) {
// i가 5면 해당 실행문을 건너 뛰고 다음 루프로 이동
  if (i === 5) {
    continue;
  }
  text = text + i;
}

console.log(text);
// 012346789
  • for-if-break : for문 내에서 break는 해당 반복문을 아예 끝내 버린다.
let text = '';

for (let i = 0; i < 10; i++) {
// i가 5면 해당 실행문을 건너 뛰고 다음 루프로 이동
  if (i === 5) {
    break;
  }
  text = text + i;
}

console.log(text);
// 01234

함수 표현식 vs 함수 선언식

  • 함수 표현식 : 변수의 값으로 함수 표현을 담아 놓은 형태. 익명 함수 표현식과 기명 함수 표현식으로 나눌 수 있다. 장점. 클로저로 사용 가능. 콜백으로 사용(다른 함수의 인자로 함수를 넘길 수 있음). 함수 선언식은 호이스팅 문제가 있으므로 함수 표현식을 사용하는 것을 추천.
let test1 = function() { // (익명) 함수표현식 : test1() 함수 바로 실행
  return '익명 함수표현식';
}

let test2 = function test2() { // 기명 함수표현식 
  return '기명 함수표현식';
}
  • 함수 선언식 : 함수 선언문은 호이스팅에 영향을 받음. 함수선언문은 코드를 구현한 위치와 관계없이 자바스크립트의 특징인 호이스팅에 따라 브라우저가 자바스크립트를 해석할 때 맨 위로 끌어 올려진다.
function test3(){
    return '함수 선언식'
}
  • 호이스팅 : 함수 안에 있는 변수 선언들을 모두 끌어올려서 해당 함수 유효 범위의 최상단에 선언하는 것. (이렇게 하면 문제가 발생할 수 있다.) 호이스팅을 막기 위해 var 대신 const, let 사용

lexical scope와 closure 예제

let age = 27;
    let name = 'jin';
    let height = 179;

    function outerFn() {
      let age = 24;
      name = 'jimin';
      let height = 178;

      function innerFn() {
        age = 26;
        let name = 'suga';
        return height;
      }

      innerFn();

      return innerFn; 
    }

    const innerFn = outerFn();
  • 외부 함수 안에 내부 함수가 있는 경우. 외부 함수만 호출 했을때는 내부함수는 실행되지 않는다. (JS가 순서대로 실행 된다고 해서 호출하지 않은 함수가 호출 되는 건 아니다.)
function A(){
    function B(){
        console.log('내부 함수 실행')
    }
    console.log('외부 함수 실행')
}

A() // 외부 함수 실행

실용적인 Closure 사용 사례

  • function factories

  • namespacing private variables/functions
let counter = (function() {
  let privateCounter = 0;
  function changeBy(val) {
    privateCounter += val;
  }
  return {
    increment: function() {
      changeBy(1);
    },
    decrement: function() {
      changeBy(-1);
    },
    value: function() {
      return privateCounter;
    }
  };
})();

console.log(counter.value()); // logs 0
counter.increment();
counter.increment();
console.log(counter.value()); // logs 2
counter.decrement();
console.log(counter.value()); // logs 1

slice(0) : 배열 값 복사할 때 사용

arr.slice는 arr의 값을 복사하여 새로운 배열을 리턴.

let arr = [1,2,3];
let newArr = arr.slice(0);
// arr과 newArr은 다른 주소를 참조한다.

call(pass) by value와 call(pass) by reference의 차이 Array를 함수의 인자로 전달할 경우, reference가 전달.

const arr = ['zero', 'one', 'two', 'three', 'four', 'five'];

    function passedByReference(refArr) {
      refArr[1] = 'changed in function';
    }
    passedByReference(arr);
    expect(arr[1]).to.equal('changed in function');

    const assignedArr = arr;
    assignedArr[5] = 'changed in assignedArr';
    expect(arr[5]).to.equal('changed in assignedArr');
    // arr.slice는 arr의 값을 복사하여 새로운 배열을 리턴
    // arr과 copiedArr은 같은 heap의 주소를 참조하지 않는다.
    const copiedArr = arr.slice(); // 깊은 복사
    copiedArr[3] = 'changed in copiedArr';
    expect(arr[3]).to.equal('three');

얕은 복사(Shallow Copy) vs 깊은 복사(Deep Copy)

얕은 복사(Shallow Copy) :

얕은 복사란 객체(array, object)를 복사할 때 복사된 값이 같은 참조(heap의 주소)를 가리키고있는 것을 말한다. 객체안에 객체가 있을 경우 한개의 객체라도 원본 객체를 참조하고 있다면 이를 얕은 복사라고 한다.

  • object.assign() / spread operator
깊은 복사(Deep Copy) :

원본과의 참조가 완전히 끊어짐

  • slice(0), 재귀함수, JSON.parse, JSON.stringify

Rest Parameter 에제

Rest Parameter는 함수의 인자를 배열로 다룰 수 있게 한다.

function returnFirstArg(firstArg) {
      return firstArg;
    }
    expect(returnFirstArg('first', 'second', 'third')).to.equal('first', 'second', 'third');

    function returnSecondArg(firstArg, secondArg) {
      return secondArg;
    }
    expect(returnSecondArg('only give first arg')).to.equal(undefined);

    // rest parameter는 spread syntax를 통해 간단하게 구현됩니다.
    function getAllParamsByRestParameter(...args) {
      return args;
    }

    // arguments를 통해 '비슷하게' 함수의 인자들을 다룰 수 있습니다. (spread syntax 도입 이전)
    // arguments는 모든 함수의 실행 시 자동으로 생성되는 '객체'입니다.
    function getAllParamsByArgumentsObj() {
      return arguments;
    }

    const restParams = getAllParamsByRestParameter('first', 'second', 'third');
    const argumentsObj = getAllParamsByArgumentsObj('first', 'second', 'third');

    expect(restParams).to.deep.equal(['first', 'second', 'third']);
    expect(Object.keys(argumentsObj)).to.deep.equal(["0", "1", "2"]);
    expect(Object.values(argumentsObj)).to.deep.equal(['first', 'second', 'third']);





© 2020.11. by creamer

Powered by CREAMer