오늘 내가 한 일 - TIL

181119 - TIL

바구레 2018. 11. 20. 10:47

주제: 자바스크립트
강의: 자바스크립트 부트캠프
날짜: 2018.11.19
강의자 : 김민태님



## 함수

가변인수, 함수 인수의 개수가 가변적인 것.
함수는 함수의 만들어진 목적대로 활용이 되려면 값의 종류와 인수의 개수를 검사해야한다.

인수의 검증.
가장 기본적인 방법은 if문을 사용해서 인수를 확인하는 방법.

함수의 사양보다 많이 전달된 인수는 함수 호출과 함께 유사배열(arguments)에 담겨서 전달된다. 이 arguments는 언제나 전달된 모든 인수가 왼쪽부터 오른쪽 순서대로 담겨진다. 함수 호출될때마다 전역으로 만들어진다. 배열처럼 사용이 가능한 것. 
배열의 기본적인 형태만 사용가능하기 떄문에 유사배열이라고 한다. 
  1.      순서대로 들어가있는 요소. 
  1.     브라켓을 사용해 순서대로 값에 접근이 가능하다. 
  1. length속성을 사용해서 길이를 구할 수 있다. 

삼항연산자

변수 = 비교식 ? 참일때 값 : 거짓일때 값;
+= 은 sum = sum + 값
sum += 값
중복되는 것을 축약함.

## es5의 가변인수 처리
가변인수를 사용하는 함수는 인자의 개수가 정해지지 않아 함수명() 인자의 내용을 알 수 없기 때문에 암묵적 사용을 해왔다
그래서 es5에서는 가변인수르르 사용하는 함수를

function sum(…args){
    …함수내용
}

function sum(a, b, …args){
    //a, b 는 인수로 받고 그 뒤는 가변인수로 처리, 
    //이 함수를 사용할 땐 최소 2개의 인수를 사용해야한다를 사용자도 알 수 있다.
}

//함수의 기본값
function sum(a = 0, b = 0, …args){
    //사용자가 함수사용시 인자를 사용하지 않을때 인자를 받는 영역에서 기본으로 넣어준다.
    // 위처럼 사용하면 사용자가 인자를 사용하지 않았을 때 처리해주는 코드 작성을 줄일 수 있다.   
}



이렇게 인자위치에 가변인수를 사용을 표시해준다.

함수는 기본적으로 객체(object)이다.
함수는 객체가 가지고 있는 특징을 모두 가지고 있다. 왜? 함수는 객체니까.
함수에서의 length는 함수가 받아들이기로 결정한 인수의 개수가 나온다.
객체기 때문에 함수명.length도 사용가능하다. 객체와 관련된 모든 동작을 수행할 수 있다. 
객체의 동적바인딩 등 객체처럼 사용가능.

function empty(x, y){

}
console.log(empty.length); //2

함수 내의 함수
function foo() {
    function get() {
        return 100;
    }

    return get();//함수 안에서만 get함수 사용이 가능, 기본적으로 호이스팅이 작동. 함수의 호이스팅은 내용이 있는 상태에서 만들어지기 때문에 호이스팅할떄 변수의 호이스팅보다 편리하다
}

let result = foo();

console.log(result);//함수바깥에서는 get함수를 호출할 수 없다

//위처럼 함수안의 함수는 잘 사용 안한다^^
//변수의 스코프와 동일하게 작용한다


함수는 문이면서 식이다.
function으로 시작하면 함수 정의문
let double = function double(){} //함수도 값이기 때문에 변수에 담는다. 이것을 함수식이라고 부른다.
함수문보다 함수식을 많이 사용한다. 객체의 메소드로 많이 사용하기 때문에. 객체안의 함수(메소드)는 무조건 함수식!

let double = function double(x) {//변수명과 함수의 이름이 같다. 존재하는 공간이 다르다는 뜻. 함수식의 이름은 함수내부에서만 호출이 가능. 변수명은 함수 바깥에서 호출.
return x * 2;
};

let reuslt = double(100);//여기서 호출하는 더블은 변수로 만들어진 더블을 호출하는 것.

console.log(result);


함수가 자기 자신을 호출하는 것을 재귀함수. 이럴때 자기 자신을 부를 이름이 필요. 함수식일 떄 함수가 이름을 가지고 있다면 함수 내부에서 자기 자신을 호출하는 경우일 수 있다.

## 세미콜론
수식의 마지막. 문은 세미콜론이 없다. 
function a(){
}//문이기 때문에 세미콜론이 없다
let a = function a(){
};//식이기 때문에 세미콜론이 있다


let utils = {
double: function(x) {
return x * 2;
}
};

let reuslt = utils.double(100); //유틸객체의 더블이라는 메소드!

console.log(result);

화살표함수(한줄함수, 람다함수)
문법의 모양이 값이 들어와서 처리를 하고 값을 반환할 것이다 집중되어있다. 기존의 함수는 코드의 묶음에 초점이 맞춰져 있음.
인수가 없으면 () 반드시 써야하고 인수가 한개면 () 생략가능. 인수가 여러개면 (a,b,c,) 괄호 반드시 필요.
코드가 여러 줄 이라면 명시적으로 리턴을 해주어야한다.

일반함수로만 만드는 것은 가능. 모두 화살표함수로 만드는 것은 불가능! 

콜백함수 - 다른 함수에게 호출을 위임한다. 
  •  계산의 결과가 너무 오래 걸려 기다리는 것이 비효율적일 때
  • 어떤 코드가 언제 실행되어야 할지 코드상으로 특정할 수 없을 때(addEventListener)
  • 호출할 함수를 특정할 수 없을 때
함수호출을 위임한다

반환값으로의 함수
함수가 값으로 반환되는 것. 반환된 함수는 함수이기 때문에 호출이 가능하다! 함수를 인자로 취하거나 함수를 반환하는 함수를 고차함수(higher-order function - 컴퓨터 프로그래밍 언어학적 관점의 용어)라고 한다.

커링 - 함수인자를 하나만 받고 두개 이상이 되면 함수로 대체하는 방법. 매우 어려운 기법.
인수개수대로 함수에 할당하는 것. 인수가 3개라면 함수를 3개로 만들어서 사용한다.
난이도가 높아서 자주 사용하지 않는다. 하지만 알고 있어야 한다!


function salePrice(discountRate, price) { //함수하나에 인수를 2개 받아서 사용하는 방법
return price - (price * (discountRate * 0.01));
}

console.log('여름 세일 - ' + salePrice(30, 567000));
console.log('겨울 세일 - ' + salePrice(10, 567000));

function discountPrice(discountRate) { //커링을 하면 두개의 인수를 나눠서 함수에 하나씩 담아서 사용, 첫번쨰 인수의 함수
return function(price) { //두번째 인수의 함수
return price - (price * (discountRate * 0.01));
}
}

//위의 함수를 화살표함수로 쓰면 아래처럼 된다.
//let discountPrice => discountRate => price => price - (price * (discountRate * 0.01));

//커링을 해서 사용하면 사용자가 아래처럼 한번에 사용할 수도 있고 맨 아래 콘솔처럼 두번에 나눠서 사용할 수도 있다.

console.log('여름 세일 - ' + discountPrice(30)(567000));
console.log('겨울 세일 - ' + discountPrice(10)(567000));

let summerPrice = discountPrice(30);
let winterPrice = discountPrice(10);

console.log('여름 세일 - ' + summerPrice(567000)); //이렇게 쓰면 레이블을 사용하지 않아도 된다. 클로저를 잘 알고 있어야한다.
console.log('겨울 세일 - ' + winterPrice(567000));

## 배열
대부분 리터럴 방식으로 만든다.
또 배열도 객체다. 객체의 특징을 모두 가지고 있다.
배열도 new 연산자를 활용해 만들 수 있다. 그런데 new연산자는 객체를 생성한다. 따라서 배열도 객체~

let myArray = ['Hello'];
let yourArray = { title: 'Hello' };

console.log(typeof myArray); //object
console.log(typeof yourArray); //object
//typeof 연산자로는 배열과 객체를 구분할 수 없다


console.log(Array.isArray(myArray)); //true
console.log(Array.isArray(yourArray)); //false
//Array객체에서 배열에 관련한 메소드를 제공한다. 



## 배열의 CRUD
create, read, update, delete 
crud를 구현해봐라 -> 만들고, 읽고, 추가하고, 제거하는 모든 동작을 한번 만들어봐라

배열의 원소 추가(update)
let myNumber = [];//빈배열 생성

for(let i=0; i < 10; i++) {
myNumbers[i] = i * 10; // 동적바인딩을 하듯 배열을 넣을 수 있다.
}

console.log(myNumbers);

myNumbers[20] = 99; //들어간다.

console.log(myNumbers);//배열의 length는 21개가 나온다, 실제 입력한 값의 개수는 11개지만 배열이 11~20번째까지 undefined를 만들어버린다
이러한 코드는 좋은 코드가 아니다. 의도하지 않은 코드의 동작이 생김.(내가 만들지 않은 undefined가 생김)



let myNumbers = [];

for(let i=0; i < 10; i++) {
myNumbers.push(i * 10);
}

console.log(myNumbers);

myNumbers.push(99);//마지막 인덱스에 추가를 한다

console.log(myNumbers); //push를 쓰자!

왜 배열의 추가가 add가 아니라  push일까?


원소꺼내기
배열의 특정 원소를 읽는 것은 간단합니다. 배열의 특정 원소를 빼내야 한다면 어떻게 할 수 있을까요? 해당 원소를 빼는 후 꺼내진 원소는 배열에서 제거되어야 합니다.

pop

pop 메소드는 배열의 마지막 원소를 반환하고 해당 원소를 배열에서 제거합니다. 즉, pop 메소드가 실행될 때 마다 배열의 크기가 1씩 감소합니다. 사용법은 간단합니다.

shift

shift 메소드는 배열에서 첫 번째 원소를 제거합니다. 그리고 제거한 원소를 반환합니다.

unshift

unshift 메소드는 하나 또는 그 이상 N개의 원소를 배열의 맨 앞에 추가하고 배열의 새로운 크기를 반환합니다.

slice

slice 메소드는 배열의 시작 위치부터 마지막 위치까지에 대한 새로운 배열을 생성하여 반환합니다. 이때 마지막 위치의 원소는 새로 생성된 배열에 포함하지 않습니다. 만약 새롭게 만들어질 배열 대상이 없다면 빈 배열을 반환합니다. slice 메소드는 원본 배열에 아무 변화를 발생시키지 않습니다.

splice

splice 메소드는 배열에 있는 원소를 삭제하거나 배열에 새 원소를 추가합니다. splice 메소드의 두 번째 인자의 역할이 삭제할 원소의 수 이며 0이면 삭제하지 않고 1이상 부터 지정한 갯수 만큼 원소를 삭제합니다.

join

join 메서드는 배열의 모든 원소를 연결해 하나의 문자열로 만듭니다. 인수로 원소와 원소 사이의 구분자로 사용될 문자열을 받으며 생략될 경우 기본 값은 콤마(,)입니다.

a = [];


a.push(1); //[1];
a.push(2); //[1,2];
a.pop(); //결과는 2가 나오고 배열은 [1] 이 된다;

push - pop
shift - unshift
get - set
join - split


이렇게 대칭되는 개념의 이름을 지으면 하나를 배워도 반대되는 것에 대해서 쉽게 알 수 있다. 

## forEach
let arr = [1,2,3,4,5];

for(let i = 0; i<arr.length ; i++){
    console.log(arr[i] * 2);
}

/////////

function double(x){
    return x *2;
}
for(let i = 0; i <arr.length; i++){
    console.log(double(arr[i]));
}



//////////
function myDouble(x){
    console.log(x * 2);
}
arr.forEach(myDouble); 

//3가지 코드 모두 결과값은 같다. 그러나 forEach를 사용하면 위의 두가지 코드에서 생길수 있는 실수할 기회를 최대한 제거한다.
//배열의 처리자 함수는 인수를 3개 넘겨준다. 사용을 하거나 안하거나 상관없이
//배열원소값, 인덱스, 원본배열전체



## map
forEach와 거의 같다. forEach는 값을 리턴하지 않는다.
map함수는 값을 리턴한다. 배열을 리턴

let arr = [1,2,3,4,5];

arr.map(x => x * 3);

// map함수가 처리한 내용을 새로운 배열에 담아서 리턴한다


map은 기존의 배열에서 어떠한 처리기를 돌려서 새로운 배열을 만든다.
기존의 배열
|    |    |    |
새로운 배열

서로 연결되어 있기 때문에 map

값을 변환할때 많이 사용한다.


노트 요약








초보 퍼블리셔의 공부정리 블로그입니다.

내용에 오류가 있거나 수정사항이 있다면 꼭 댓글 부탁드립니다




'오늘 내가 한 일 - TIL' 카테고리의 다른 글

181126 - TIL  (0) 2018.11.27
181121 - TIL  (0) 2018.11.22
181114 - TIL  (0) 2018.11.14
181112 - TIL  (0) 2018.11.14
181108 - TIL  (0) 2018.11.08