JavaScript

1. Scope 와 Closures

함수 내부에서 변수를 선언할 때, 그 변수는 함수 내부에서만 접근할 수 있습니다. 이런 변수들은 함수의 스코프 위에 존재한다고 말합니다. 함수 내부에서 함수를 선언할 때, 내부의 함수는 클로저라고 불립니다. 이 클로저는 외부 함수에서 생성된 변수들에 접근할 수 있는 권한을 가지고 있습니다.

Scope

let message = "Outer"; // 전역 스코프

function getMessage() {
  return message;
}

function overrideMessage() {
  let message = "Inner"; // 값 "Outer"가 대입된 함수 바깥 변수 message와 이것은 다른 변수
  return message;
}

getMessage();
// "Outer"
overrideMessage();
// "Inner"
console.log(message);
// "Outer"

Closures

함수 내부에 함수를 작성할 때마다, 여러분은 클로저를 생성한 것입니다. 내부에 작성된 함수가 바로 클로저죠.

function makeIncreaseByFunction(increaseByAmount) {
  return function (numberToIncrease) {
    return numberToIncrease + increaseByAmount;
  };
}

const increaseBy3 = makeIncreaseByFunction(3);
const increaseBy5 = makeIncreaseByFunction(5);

increaseBy3 // -> 함수이며, 리턴값은 아래와 같다
// ƒ (numberToIncrease) {
//     return numberToIncrease + increaseByAmount;
//   }

increaseBy3(10) + increaseBy5(10)
// 28

2. 함수에서 전달인자와 매개변수

함수에서 매개변수와 전달인자 수의 관계

function returnFirstArg(firstArg) { // 매개변수를 한 개만 설정한 경우
  return firstArg;
}

returnFirstArg("first", "second", "third") // 전달인자도 처음 한 개만 전달된다.
// "first"


function returnSecondArg(firstArg, secondArg) { // 매개변수가 두 개인데
  return secondArg;
}

returnSecondArg("only give first arg") // 전달인자가 하나이면, undefined.
// undefined

Rest 파라미터

Rest 파라미터 구문은 정해지지 않은 수(an indefinite number, 부정수) 인수를 배열로 나타낼 수 있게 합니다. (Internet Explorer 지원되지 않음)
[ Rest 파라미터 | MDN ]

function returnAllArgs(...args) { // ...args로 모든 전달인자를 받음
  let argumentsText = '';

  for (let i = 0; i < args.length; i += 1) {
    argumentsText = argumentsText + args[i];
  }

  return argumentsText;
}

returnAllArgs("first", "second", "third")
// "firstsecondthird"
function sum(...theArgs) {
  return theArgs.reduce((previous, current) => {
    return previous + current;
  });
}

console.log(sum(1, 2, 3));
// expected output: 6

console.log(sum(1, 2, 3, 4));
// expected output: 10

전개 구문

전개 구문([...])을 사용하면 배열이나 문자열과 같이 반복 가능한 문자를 0개 이상의 인수 (함수로 호출할 경우) 또는 요소 (배열 리터럴의 경우)로 확장하여, 0개 이상의 키-값의 쌍으로 객체로 확장시킬 수 있습니다. (Internet Explorer 지원되지 않음)
[ 전개 구문 | MDN ]

function sum(x, y, z) {
  return x + y + z;
}

const numbers = [1, 2, 3];

console.log(sum(...numbers));
// expected output: 6

변수에 함수를 대입하기

const appendRules = function (name) {
  return name + " rules!";
};

const appendDoubleRules = function (name) {
  return name + " totally rules!";
};

const praiseSinger = { givePraise: appendRules }; // 객체의 value로 함수를 선언함
praiseSinger.givePraise("John")
// "John rules!"

praiseSinger.givePraise = appendDoubleRules; // 객체의 value값을 다른 함수로 변경함
praiseSinger.givePraise("Mary")
// "Mary totally rules!"

3. 생성자

Date()

시간의 특정 지점을 나타내는 Date 객체를 생성합니다. Date 객체는 1970년 1월 1일 UTC(국제표준시) 00:00으로부터 지난 시간을 밀리초로 나타내는 유닉스 타임스탬프를 사용합니다.
[ Date | MDN ]

Date(); // 현재 날짜를 반환함
// "Wed Aug 07 2019 16:12:45 GMT+0900 (한국 표준시)"

var today = new Date(); // 변수에 현재 일시를 대입
var birthday = new Date("December 17, 1995 03:24:00"); // 특정 일시를 대입시키기
var birthday = new Date(95,11,17);
var birthday = new Date(95,11,17,3,24,0);

getFullYear()

getFullYear() 메서드는 주어진 날짜의 현지 시간 기준 연도를 반환합니다.
[ Date.prototype.getFullYear() | MDN ]

var moonLanding = new Date('July 20, 69 00:20:18');
console.log(moonLanding.getFullYear());
// expected output: 1969

Array()

Array 생성자는 주어지는 인수에 따라 두 가지 서로 다른 방식으로 동작을 합니다.
수 타입의 인수가 하나 주어질 때는 해당 수 만큼의 길이를 갖는 비어있는 배열을 만들어 냅니다. 만약 인수가 양의 정수가 아니라면 에러를 냅니다. 이 외에 다른 모양으로 인수가 주어지면 그 인수들을 요소로 갖는 배열을 생성합니다.

new Array(1); // [empty]
new Array(1000); // [empty × 1000]
new Array(1, 2, 3); // [1, 2, 3]

Array.of()

이렇게 일관적이지 못한 생성자의 동작방식 때문에, ES2015에 Array.of 정적 메소드가 추가되었습니다. 이 메소드는 위의 2번 방식으로만 동작합니다. 따라서, Array 생성자를 사용할 때에는 1번 방식으로만 사용하고, 2번 방식의 코드를 작성할 때는 생성자 대신 Array.of 정적 메소드를 사용하세요.

new Array(1, 2, 3); // 이렇게 하지 마세요!
Array.of(1, 2, 3) // 대신 이렇게 하세요.

// `Array.of` 정적 메소드는 인수가 하나이더라도 그 인수를 요소로 갖는 배열을 반환합니다.
Array.of(1); // [1]

// 생성자는 이런 용도로만 사용하세요.
new Array(1000); // [empty × 1000]

Array.of는 인자의 수나 유형에 관계없이 가변 인자를 갖는 새 Array 인스턴스를 만듭니다. Array.of()와 Array 생성자의 차이는 정수형 인자의 처리 방법에 있습니다. Array.of(7)은 하나의 요소 7을 가진 배열을 생성하지만 Array(7)은 length 속성이 7인 빈 배열을 생성합니다.
[ Array.of() | MDN ]

Array.of(7);       // [7] 
Array.of(1, 2, 3); // [1, 2, 3]

Array(7);          // [ , , , , , , ]
Array(1, 2, 3);    // [1, 2, 3]

4. 배열 메서드

forEach()

주어진 함수를 배열 요소 각각에 대해 실행합니다. 반환값은 undefined입니다.
[ Array.prototype.forEach() | MDN ]

let numbers = [1,2,3];
let result = [];

let isEven = function (item) {
  result.push((item % 2) === 0);
};

numbers.forEach(isEven);

console.log(result)
// [false, true, false]
console.log(numbers)
// [1,2,3]
// for 반복문을 forEach로 바꾸기
const items = ['item1', 'item2', 'item3'];
const copy = [];

// 이전
for (let i=0; i<items.length; i++) {
  copy.push(items[i]);
}

// 이후
items.forEach(function(item){
  copy.push(item);
});

every()

배열 안의 모든 요소가 주어진 판별 함수를 통과하는지 테스트합니다.
callback이 모든 배열 요소에 대해 참(truthy)인 값을 반환하는 경우 true, 그 외엔 false를 반환합니다. 빈 배열에서 호출하면 무조건 true를 반환합니다. every는 호출한 배열을 변형하지 않습니다.
[ Array.prototype.every() | MDN ]

let onlyEven = [2,4,6];
let mixedBag = [2,4,5,6];

let isEven = function(x) {
  return x % 2 === 0;
};

console.log(onlyEven.every(isEven)); // true
console.log(mixedBag.every(isEven)); // false
// 배열의 모든 요소가 10보다 더 큰지 테스트합니다.
function isBigEnough(element, index, array) {
  return element >= 10;
}
[12, 5, 8, 130, 44].every(isBigEnough);   // false
[12, 54, 18, 130, 44].every(isBigEnough); // true

some()

배열 안의 어떤 요소라도 주어진 판별 함수를 통과하는지 테스트합니다.
callback이 어떤 배열 요소라도 대해 참인(truthy) 값을 반환하는 경우 true, 그 외엔 false를 반환합니다. 빈 배열에서 호출하면 무조건 false를 반환합니다. some은 호출한 배열을 변형하지 않습니다.
[ Array.prototype.some() | MDN ]

let onlyEven = [2,4,6];
let mixedBag = [2,4,5,6];

let isEven = function(x) {
  return x % 2 === 0;
};

console.log(onlyEven.some(isEven)); // true
console.log(mixedBag.some(isEven)); // true
// 배열 내 요소 중 하나라도 10보다 큰지 판별합니다.
function isBiggerThan10(element, index, array) {
  return element > 10;
}
[2, 5, 8, 1, 4].some(isBiggerThan10);  // false
[12, 5, 8, 1, 4].some(isBiggerThan10); // true

map()을 활용해 배열 속 객체를 재구성하기

[ Array | MDN ]

// 오브젝트의 배열을 받아 각 오브젝트를 다른 형태으로 재구성해 새로운 배열을 만듭니다.
var kvArray = [{key:1, value:10},
               {key:2, value:20},
               {key:3, value: 30}];

var reformattedArray = kvArray.map(function(obj){ 
   var rObj = {};
   rObj[obj.key] = obj.value;
   return rObj;
});
// reformattedArray는 [{1:10}, {2:20}, {3:30}]

// kvArray는 그대로
// [{key:1, value:10},
//  {key:2, value:20},
//  {key:3, value: 30}]

Terminal

터미널을 처음 열었을 때 : root 폴더에서 시작한다.

ls : 파일 목록 보기

현재 위치한 폴더 내에 속한 파일 및 폴더 목록을 보여주는 명령어

➜  ~ ls // 현재 위치한 폴더 안 폴더와 파일들을 보여준다.
Applications         Documents            Library              Pictures
Creative Cloud Files Downloads            Movies               Public
Desktop              Dropbox              Music
➜  ~ ls -a // 숨겨진 파일까지 보여준다.
.                             .gitignore_global             Desktop
..                            .hgignore_global              Documents
.CFUserTextEncoding           .oh-my-zsh                    Downloads
.DS_Store                     .shell.pre-oh-my-zsh          Dropbox
.Trash                        .vscode                       Library
.bash_history                 .wacom                        Movies
.cups                         .zsh_history                  Pictures
.dropbox                      .zshrc                        Public
.gitconfig                    Applications
.gitflow_export               Creative Cloud Files

cd : 위치 이동

➜  ~ cd Documents //Documents 폴더로 이동
➜  Documents cd .. // 상위 폴더로 이동
➜  ~
// 이동하고자 하는 폴더 이름을 다른 폴더와 구분될 만큼 적고 tab키를 누르면 파일명이 자동완성된다.

cp : 복사

➜  ~ cp test.txt test-copy.txt // test.txt 파일을 test-copy.txt라는 이름으로 복사본을 만든다

➜  ~ cp FOLDER FOLDER2 // -R 옵션을 사용하지 않으면(내용물을 함께 복사) 복사되지 않는다.
➜  cp: FOLDER is a directory (not copied).

➜  ~ cp -r FOLDER FOLDER2 // FOLDER 폴더를 FOLDER2라는 이름으로 복사 성공

mv : 파일 이동, 이름 변경

➜  ~ mv test.txt test-yes.txt // 이름 변경
➜  ~ mv test-yes.txt FOLDER // FOLDER 폴더로 testyes.txt이동

rm : 삭제

➜  ~ rm -i test-copy.txt // 옵션 -i : 삭제할 것인지 확인한다. 그렇지 않으면 바로 지운다.
➜  remove test-copy.txt? Y // Y혹은 N을 입력. 지워진 파일은 휴지통에 들어가지 않는다.
➜  ~ rm -r FORDER // 옵션 -r : FORDER 폴더를 내용과 함께 삭제한다.

man : 매뉴얼 보기

➜  ~ man ls // ls(혹은 어떤 명령어든) 매뉴얼을 볼 수 있다. 매뉴얼 페이지에서 나가려면 q를 입력한다.
:  q // 보고 있는 페이지에서 나간다.

그 외 명령어

➜  ~ touch [file_name] // 빈 파일 생성
➜  ~ mkdir [dir_name] // 디렉토리 생성
➜  ~ cat [file_name] // 텍스트 형태의 파일 내용 확인
➜  ~ open . // 현재 폴더를 macOS Finder에서 보기
➜  ~ code . // 현재 폴더를 VS Code 에디터로 열기

2019.08.11 티스토리 블로그에 작성한 글을 velog로 옮김