TIL 12일차

ᄋᄋ·2021년 11월 25일
0

출처: javascript info, MDN

스코프 고급

Strict Mode

이 명령어가 스크립트 최상단에 오면 스크립트 전체가 “모던한” 방식으로 동작함. (최상단에 안 오면 엄격 모드 실행 안 됨. 또한 "use strict"의 위에는 주석만 사용할 수 있음.)

"use strict"는 스크립트 최상단이 아닌 함수 본문 맨 앞에 올 수도 있음. 이렇게 하면 오직 해당 함수만 엄격 모드로 실행됨. (참고로, use strict를 취소할 방법은 없음.)

모던 자바스크립트는 '클래스’와 '모듈’이라 불리는 진일보한 구조를 제공함. 이 둘을 사용하면 use strict가 자동으로 적용됨. 따라서 코드를 클래스와 모듈을 사용해 구성한다면 "use strict"를 생략해도 됨.

즉시 실행 함수 표현식(IIFE)

즉시 실행 함수 표현(IIFE, Immediately Invoked Function Expression)은 정의되자마자 즉시 실행되는 Javascript Function을 말함.

( function() { } )(); 

첫 번째는 괄호((), Grouping Operator)로 둘러싸인 익명함수(Anonymous Function)임. 이는 전역 스코프에 불필요한 변수를 추가해서 오염시키는 것을 방지할 수 있을 뿐 아니라 IIFE 내부안으로 다른 변수들이 접근하는 것을 막을 수 있는 방법임.

두 번째 부분은 즉시 실행 함수를 생성하는 괄호()임. 이를 통해 자바스크립트 엔진은 함수를 즉시 해석해서 실행함.

자바스크립트는 function 이라는 키워드를 만나면 함수 선언문이 시작될 것이라 예상함. 그런데 함수 선언문으로 함수를 만들 땐 반드시 함수의 이름이 있어야 함.
또한 자바스크립트는 함수 선언문으로 정의한 함수를 정의와 동시에 바로 호출하는 것을 허용하지 않음.

함수를 괄호로 감싸면 자바스크립트가 함수를 함수 선언문이 아닌 표현식으로 인식하도록 속일 수 있음. 함수 표현식은 이름이 없어도 괜찮고, 즉시 호출도 가능함.

괄호를 사용하는 방법 말고도, 자바스크립트가 함수 표현식이라고 인식하게 해주는 다른 방법들이 있음.

// IIFE를 만드는 방법

(function() {
  alert("함수를 괄호로 둘러싸기");
})();

(function() {
  alert("전체를 괄호로 둘러싸기");
}());

!function() {
  alert("표현식 앞에 비트 NOT 연산자 붙이기");
}();

+function() {
  alert("표현식 앞에 단항 덧셈 연산자 붙이기");
}();

그런데 모던 자바스크립트에선 이렇게 코드를 작성할 필요가 없음.


+더 공부해야 할 개념들

변수 호이스팅과 TDZ(Temporal Dead Zone)

1. 선언 | 2. 초기화 | 3. 할당

var : 선언,초기화(변수에 undefined 할당) 수준까지 호이스팅 가능.

a;		// undefined
var a;

let, const : 선언 수준에서 호이스팅 가능.(초기화 X --> 에러 발생)

b;
let b;	//Uncaught ReferenceError: v is not defined at <anonymous>:1:1

b; 	// undefined

함수 선언식 호이스팅: 선언, 초기화, 할당

test();		// 'hello'

function test() {
    return 'hello';
}

함수 표현식 호이스팅 : 선언 (함수 선언식과 표현식 비교)

클로져
Execution context
binding의 개념과 call, apply, bind


Spread/Rest 문법

Spread 문법

주로 배열을 풀어서 인자로 전달하거나, 배열을 풀어서 각각의 요소로 넣을 때에 사용함.

function sum(x, y, z) {
  return x + y + z;
}
const numbers = [1, 2, 3];
sum(...numbers) 

배열 합치기

let parts = ['shoulders', 'knees'];
let lyrics = ['head', ...parts, 'and', 'toes'];

//또는
let arr1 = [1,2,3,4];
let arr2 = [5,6,7];

let sum = [...arr1, ...arr2];		//[1,2,3,4,5,6,7]

concat으로 합치면, arr1.concat(arr2);

배열 복사

let arr = [1, 2, 3];
let arr2 = [...arr]; // arr.slice() 와 유사

객체에서 사용하기

let obj1 = { foo: 'bar', x: 42 };
let obj2 = { foo: 'baz', y: 13 };

let clonedObj = { ...obj1 };
let mergedObj = { ...obj1, ...obj2 };

Rest 문법

파라미터를 배열의 형태로 받아서 사용할 수 있음. 파라미터 개수가 가변적일 때 유용함.

function sum(...theArgs) {
  return theArgs.reduce((previous, current) => {
    return previous + current;
  });
}
sum(1,2,3) 
sum(1,2,3,4) 

함수에서 나머지 파라미터 받아오기

function myFun(a, b, ...manyMoreArgs) {
  ...
}

myFun("one", "two", "three", "four", "five", "six");

//a === "one",  b === "two", manyMoreArgs === ["three", "four", "five", "six"]

구조 분해 (Destructing)

Spread 문법을 이용하여 값을 해체한 후, 개별 값을 변수에 새로 할당하는 과정을 말함.

분해 후 새 변수에 할당

배열
const [a, b, ...rest] = [10, 20, 30, 40, 50];

선언에서 분리한 할당도 가능.

let a, b, rest;
[a, b, ...rest] = [10, 20, 30, 40, 50];

객체
const {a, b, ...rest} = {a: 10, b: 20, c: 30, d: 40}

객체에서 구조 분해 할당을 사용하는 경우,

선언(const, let, var)과 함께 사용하지 않으면 에러가 발생할 수 있음.
선언없이 할당하는 경우, ()괄호로 감싸면 유효함.
({a, b} = {a:1, b:2})는 var {a, b} = {a:1, b:2}와 같음.

새로운 변수 이름으로 할당하기

var o = {p: 42, q: true};
var {p: foo, q: bar} = o;

console.log(foo); // 42
console.log(bar); // true

기본값

객체로부터 해체된 값이 undefined인 경우, 변수에 기본값을 할당할 수 있음.

var {a = 10, b = 5} = {a: 3};

console.log(a); // 3
console.log(b); // 5

기본값 갖는 새로운 이름의 변수에 할당하기

var {a: aa = 10, b: bb = 5} = {a: 3};

console.log(aa); // 3
console.log(bb); // 5

함수 매개변수의 기본값 설정하기

ES2015 버전

function drawES2015Chart({size = 'big', cords = { x: 0, y: 0 }, radius = 25} = {}) {
  console.log(size, cords, radius);
  // 차트 그리기 수행
}

drawES2015Chart({
  cords: { x: 18, y: 30 },
  radius: 30
});

JavaScript Koans 과제에서 몰랐던 부분

Array.from()

Array.from() 메서드는 유사 배열 객체(array-like object)나 반복 가능한 객체(iterable object)를 얕게 복사해 새로운Array 객체를 만듬.

console.log(Array.from('foo'));
// expected output: Array ["f", "o", "o"]

console.log(Array.from([1, 2, 3], x => x + x));
// expected output: Array [2, 4, 6]

'행동'을 하는 표현식은 그 결과가 반영됨.

let a = 1;
function work() {
  a = 2;
}
a;	// 1

BUT,
let a = 1;
function work() {
  a = 2;
}

const result = work();
a;	// 2

const result = work(); : 이 코드는 함수 work를 실행시키고, 변수 result에 함수 work의 리턴값을 할당함.


slice

const arr = ['peanut', 'butter', 'and', 'jelly'];

arr.slice(2, 2)).to.deep.equal([]);
arr.slice(3, 0)).to.deep.equal([]);
arr.slice(5, 1)).to.deep.equal([]);

Object.assign({}, obj);

Object.assign을 통한 복사는 값이 reference variable(객체,배열)이면 주소만 복사함. 즉, 속성 값을 복사하는데 그 값이 참조형이면 주소를 복사함.

얕은 복사(shallow copy)

: 주소값(reference)만 복사하는 것

깊은 복사(deep copy)

: 값 자체를 복사하는 것.

+)
가이드가 될 만한 학습자료1
가이드가 될 만한 학습자료2


str.repeat(n) : str을 n번 반복

let str = 'abc';
str.repeat(3);		// 'abcabcabc'

"arguments 객체는 유사배열이다."


this

method는 '어떤 객체의 속성으로 정의된 함수'
전역 변수에 선언한 함수도 웹페이지에서 window 객체의 속성으로 정의된 함수임.
함수가 호출될 때마다 어떠한 객체의 method일 텐데, 그 '어떠한 객체'를 묻는 것이 this임. 전역 선언한 함수의 this는 window임.

this는 함수의 호출에 따라서 값이 달라지기도 함. (+ apply나 call, bind)

근데, 화살표 함수는 다름. 자신의 this가 없음.

화살표 함수에서의 this는 자신을 감싼 정적 범위(lexical context)임. (전역에서는 전역 객체를 가리킴.)

일반 변수 조회 규칙(normal variable lookup rules)을 따르기 때문에, 현재 범위에서 존재하지 않는 this를 찾을 때, 화살표 함수 바로 바깥 범위에서 this를 찾음.

profile
개발자A

0개의 댓글