자바스크립트 완벽 가이드 7판 스터디
책의 목차를 따라가며 관련 내용을 학습하고 공유하는 스터디입니다.
1. Function Definition - 함수 정의
2. 함수 호출
3. Default Parameters
4. Rest Parameters, Arguments
5. Arrow Function - 화살표 함수
6. Execution Context - 실행컨텍스트
7. This
Parameters - 매개변수
Argument - 인수
Return Value
Function Definition
로 생성한다.함수 선언문
, 함수 표현식
, 화살표 함수
, 생성자 함수
function doSomething(a, b, c) {
return a + b + c;
}
doSomething(1, 2, 3); // 호이스팅
var doSomething = function doSomething(a, b, c) {
return a + b + c;
};
doSomething(1, 2, 3); // EReferenceError: doSomething is not defined
const doSomething = function (a, b, c) {
return a + b + c;
};
doSomething(1, 2, 3); // 6
doSomething.name; // 'doSomething'
const doSomething = function func(a, b, c) {
return a + b + c;
};
doSomething(1, 2, 3); // 6
console.log(doSomething.name); // 'func'
func(1, 2, 3); // ReferenceError: func is not defined
function Person(nickname, age) {
this.nickname = nickname;
this.age = age;
this.sleep = function () {
console.log(`${this.nickname} is sleeping`);
};
}
const sangbeomheo = new Person('husbumps', 15);
sangbeomheo.nickname; // husbumps
sangbeomheo.age; // 15
sangbeomheo.sleep(); // husbumps is sleeping
func(1,2,3)
obj.method(1,2,3)
new Person(1,2,3)
func.call(thing)
undefined
가 된다.function sum(x = 0, y = 0) {
// Default Parameters가 없을 때는 이렇게 직접 체크를 해줬다.
// x = x || 0;
// y = y || 0;
return x + y;
}
sum(10); // 10 + 0 = 10
sum(); // 0 + 0 = 0
Rest Parameters
추가Rest Parameters
를 사용하면 매개변수의 개수가 동적일 때 인수 목록을 배열로 전달받을 수 있다.arguments
가 갖은 문제점과 번거로움을 보완arguments
는 유사배열이라서 배열 메소드를 사용하려면 배열로 변환해줘야한다.arguments
객체를 갖지 않는다.function sum(...numbers) {
console.log(numbers); // Array(5) [1,2,3,4,5]
console.log(arguments); // Arguments(5) [1,2,3,4,5]
return numbers.reduce((a, c) => a + c);
}
console.log(sum(1, 2, 3, 4, 5)); // 15
function sum(...numbers) {
console.log(numbers); // Array(5) [1,2,3,4,5]
return numbers.reduce((a, c) => a + c);
}
const arr = [1, 2, 3, 4, 5];
console.log(sum(...arr)); // 15
=>
를 사용해 함수를 정의한다.const sum = (x, y) => {
return s + y;
};
const sum = (x, y) => s + y; // {}를 생략할 수 있다. 이 경우 'return'도 생략
non-constuctor
const Arrow = () => {};
new Arrow(); // TypeError: Arrow is not a constructor
// Arguments
function outer(a, b, c) {
console.log(arguments); // 1
function inner1(a, b, c) {
console.log(arguments); // 2
}
const inner2 = (a, b, c) => {
console.log(arguments); // 3
};
inner1(4, 5, 6);
inner2(7, 8, 9);
}
outer(1, 2, 3);
// 1 [Arguments] { '0': 1, '1': 2, '2': 3 }
// 2 [Arguments] { '0': 4, '1': 5, '2': 6 }
// 3 [Arguments] { '0': 1, '1': 2, '2': 3 } // 상위함수 바인딩
전역공간
함수
eval
module
전역공간
: 자바스크립트 코드가 실행되는 순간에 행성되고 전체 코드가 끝날 때 종료module
: import 될 때 행성, 해당 코드가 전부 끝날 때 종료함수
: 함수가 실행될 때 생성, 함수 내부 코드가 전부 끝날 때 종료함수
라고 묶어서 볼 수 있다.실행컨텍스트는 함수를 실행할 때 필요한 환경정보를 담은 객체
// global start
var a = '1';
function foo() {
// foo start
function bar() {
// bar start
console.log(a); // undefined
var a = '3';
console.log(a); // 3
// bar end
}
bar();
console.log(a); // 1
// foo end
}
foo();
console.log(a); // 1
// global end
Variable Environment
Lexical Environment
Variable Environment
에 먼저 정보를 담고 이를 복사해서 Lexical Environment
를 만든다.environmentRecord
: 환경 기록. 현재 컨텍스트 내부의 식별자 정보 (호이스팅)outerEnvironmentReference
: 외부 환경 참조. (스코프 체인)This
environmentRecord
에 담는다.Hoisting(호이스팅)
이라고 한다. Chapter3. 호이스팅 정리 부분a();
function a() {
return 'a';
}
var b = 123;
var c = function () {
return 'c';
};
// environmentRecord start
function a() {
return 'a';
}
var b;
var c;
// environmentRecord end
a();
var b = 123;
var c = function () {
return 'c';
};
Lexical Environment
를 참조한다.outerEnvironmentReference
에 의해서 만들어진다.this
전역공간에서의 **this**
는 **전역 객체**
를 가리킨다.
// 브라우저에서
console.log(this); // Window {...}
var a = 1;
console.log(a); // 1
console.log(window.a); // 1
console.log(this.a); // 1
// node.js에서
console.log(this); // Object [global] {...}
this
함수 호출은 전역객체가 하기때문에 this
는 전역 객체
를 가리킨다.
전역 객체
전역 객체
를 가리킨다.Arrow Function(화살표 함수)
디스 바인딩을 하지 않는다.function a() {
console.log(this);
}
a(); // Window (브라우저 실행 시)
function b() {
function c() {
console.log(this);
}
c(); // Window (브라우저 실행 시)
}
b();
this
메서드를 호출한 주체
가 this
가 된다.
.
앞이 this
!var func = function (x) {
console.log(this, x);
};
func(1);
var obj = {
method: func,
};
obj.method(2);
obj['method'](2);
// Window
// { method: f } 2
// { method: f } 2
// 익명함수는 그대로인데 이를 변수에 담아 호출한 경우,
// obj객체의 프로퍼티에 할당해서 메소드로 호출한 경우
// 어디에 작성됐는지가 아니라 어디서 어떻게 호출됐는지가 This를 결정
const outer = {
inner: function () {
console.log(this);
function innerFunc() {
console.log(this);
}
innerFunc();
},
};
outer.inner();
// {inner: ƒ}
// Window
const a = {
b: {
c: function () {
console.log(this);
},
},
};
a.b.c();
// {c: f}
var a = 10;
const obj = {
a: 20,
b: function () {
console.log(this.a);
function c() {
console.log(this.a);
}
c();
},
};
obj.b();
// 20
// 10
call
, apply
, bind
를 사용 (ES5)var a = 10;
const obj = {
a: 20,
b: function () {
var _this = this;
console.log(this.a);
function c() {
console.log(_this.a);
}
c();
const _c = () => {
console.log(this.a);
};
_c();
},
};
obj.b();
// 20
// 20
// 20
function example(a, b, c) {
console.log(this, a, b, c);
}
const obj = {
x: 'x',
};
example(1, 2, 3); // Window, 1, 2, 3
example.call(obj, 1, 2, 3); // {x: 'x'}, 1, 2, 3
example.apply(obj, [1, 2, 3]); // {x: 'x'}, 1, 2, 3
const boundExample1 = example.bind(obj);
boundExample1(1, 2, 3); // {x: 'x'}, 1, 2, 3
const boundExample2 = example.bind(obj, 1, 2);
boundExample2(3); // {x: 'x'}, 1, 2, 3
this
기본적으로는 함수내부에서와 동일
⇒ this는 전역객체
const callback = function () {
console.log(this);
};
const obj = {
a: 1,
b: function (fn) {
fn();
},
};
obj.b(callback);
// Window
function b() {
console.log(this);
}
document.body.innerHTML = '<div id="a">Hello</div>';
document.querySelector('#a').addEventListener('click', function () {
console.log(this);
});
// div#a (DOM Element)
// 이벤트리스너 함수는 콜백함수를 실행할 때 이벤트가 발생한 타겟 엘리먼트로 한다고 정해져있음
this
새로 만드는 인스턴스 객체 그 자체가 **this**
가 된다.
function Person(name, age) {
this.name = name;
this.age = age;
}
const sangbeomheo = Person('상범', 10);
console.log(sangbeomheo.name, sangbeomheo.age); // 상범, 10