// var registerUserInfo = function() {};
var registerUserInfo = function() {
console.log('registerUserInfo 함수 실행');
};// function getUserInfo() { }
function getUserInfo() {
console.log('getUserInfo 함수 실행');
}- 함수인지 검증 후 실행
if ( isFunction(registerUserInfo) ) {
registerUserInfo();
}isFunction(getUserInfo) && getUserInfo();var g_scope = '전역 변수';- 호이스팅 발생 시 순서
- 일단 함수 안에서 찾는다. (지역)
- 없으면 다음으로 변수 영역에서 찾는다.
- 없으면 다음으로 Parameters(매개변수) 영역에서 찾는다.
- 없으면 다음으로 함수를 포함하는 상위 영역에서 찾는다.
- 없으면 다음으로 전역에서 찾는다.
- 그래도 없으면 ReferenceError 발생!
function localScope() {
console.log('g_scope:', g_scope);
// 아래의 함수값이 어떻게 나올까?
innerScopeFn();
// 1)
function innerScopeFn() {
var l_scope = '지역 변수';
console.log('l_scope:', l_scope);
}
// ——> '지역 변수'
}function localScope() {
console.log('g_scope:', g_scope);
// 아래의 함수값이 어떻게 나올까?
innerScopeFn();
// 2)
var innerScopeFn = function() {
var l_scope = '지역 변수';
console.log('l_scope:', l_scope);
}
// ——> typeError
// Why? 함수 표현식은 변수만 호이스팅되기 때문에 innerScopeFn 값은 undefined가 된다.
// 따라서 innerScopeFn는 함수가 아니게 되므로 실행 시 콘솔에는 typeError가 뜬다.
}- 전역스코프에서 this는 window 이다.
- this는 윈도우를 지시한다.
console.log(this === window); // true
a = 37;
console.log(window.a); // 37
this.b = "this === window";
console.log(window.b) //"this === window"
console.log(b) //"this === window"- Simple call
- 다음 코드는 엄격 모드this 가 아니며 호출에 의해 값이 설정되지 않았으므로 전역 객체this가 기본값이 됩니다.
function f1() {
return this;
}
// In a browser:
f1() === window; // the window is the global object in browsers
// In Node:
f1() === global; // node에서 전역은 global이다.- 엄격 모드에서는 this실행 컨텍스트를 입력 할 때 설정 한 값이 그대로 유지되므로 다음과 같은 경우 this 기본값으로 설정됩니다
function f2() {
'use strict'; // strict mode 설정
return this;
}
f2() === undefined; // true-
따라서 엄격 모드this에서 실행 컨텍스트에 의해 정의되지 않은 경우에는 정의되지 않은 상태로 유지됩니다.
-
this 하나의 컨텍스트에서 다른 컨텍스트로 값을 전달하려면 call 을 사용 하거나 다음을 apply를 쓰면 됩니다.
function f3() {
return this;
}
f3.call(this) === window; // global object
function f4() {
this.herp = 'derp';
}
function Thing() {
this.thisIsEasyToUnderstand = 'just kidding';
f4.call(this); // f4함수의 속성을 값을 Thing에서도 쓸수 있게 해준다. 상속의 개념!! 빌려쓸수 있다!!!
}
var thing = new Thing();
// thing = {thisIsEasyToUnderstand: 'just kidding', herp: 'derp'}; function add(c, d) {
return this.a + this.b + c + d;
}
var o = {a: 1, b: 3};
add.call(o, 5, 7); // this === o
// this.a + this.b + c + d -> a + b + c + d
// 1 + 3 + 5 + 7 -> 16
add.apply(o, [10, 20]);
// this.a + this.b + c + d -> a + b + c + d
// 1 + 3 + 10 + 20 -> 34- call apply, 의 차이는 두번째 인자를 배열로 받느냐 콤마로 받느냐 차이 입니다.
function f() {
return this.a;
}
var g = f.bind({a: 'azerty'});
console.log(g()); // azerty
// this.a = azerty
var h = g.bind({a: 'yoo'}); // bind only works once!
// hard binding 이라서 attach는 한번만 가능하다.
console.log(h()); // azerty
var o = {a: 37, f: f, g: g, h: h};
console.log(o.f(), o.g(), o.h()); - a:37, f:function f() { return this.a; }, g: f.bind({a: 'azerty'}), h: g.bind({a: 'yoo'})
- 순서로 해석 되어지므로 o.f() -> 37, o.g() -> azerty, o.h() -> azerty
- JavaScript의 모든 함수 스코프에는 arguments라는 특별한 변수가 있으며 이 변수는 함수에 넘겨진 모든 인자에 대한 정보가 담겨 있다.
- 예를 들어 함수에 인수 셋이 전달된 경우 아래 코드와 같이 참조 가능하다.
arguments[0]
arguments[1]
arguments[2]- arguments 객체는 length 속성을 가지고 있지만 Array라고 할 수는 없다. 그러므로 pop, push, slice 같은 array의 표준 method 가 없다.
- 하지만 실제 아래 예시와 같이 Array로 변환은 가능하다 .
var args = Array.prototype.slice.call(arguments);- 매개변수를 처리에 관해 JavaScript는 상당히 유연하다.
- 자바 스크립트 함수 정의는 매개 변수에 대한 데이터 유형을 지정하지 않는다
- 자바 스크립트 함수는 전달 된 인수에 유형 검사를 수행하지 않는다
- 자바 스크립트 함수는 수신 된 인수의 수를 확인하지 않는다.
자기 자신을 재호출 하는 함수를 말한다. (ex : 팩토리얼 )
function add(){
add();
}자기 자신의 수에 1 작은 수를 곱하고 또 1작은 수를 곱하고 해서 1작은 수가 1이 될때까지 곱한 값.
1! = 1 = 1
2! = 2 x 1 = 2
3! = 3 x 2 x 1 = 6
4! = 4 x 3 x 2 x 1 = 24
5! = 5 x 4 x 3 x 2 x 1 = 120
function factorial(n) {
// ㅜㅜn<2 인 경우
if ( n < 2 ) { return 1; }
// n>=2 인 경우
// n의 값을 기억하기 위한 result 변수 선언.
var result = n;
do { result *= --n; }
while(n > 1);
return result;
}function factorial(n) {
if ( n < 2 ) { return 1; }
// n = 5 인 경우 ,
// 5 * factorial(4)
// 5 * 4 * factorial(3)
// 5 * 4 * 3 * factorial(2)
// 5 * 4 * 3 * 2 * factorial(1)
// ==> factorial(5) 는 5 x 4 x3 x 2 x 1 이 성립한다.
return n * factorial(--n);
}