자바스크립트 들어가기 3

심민기·2022년 4월 8일
0

자바스크립트

목록 보기
4/11
post-thumbnail

시즌 2! 함수!

함수형 언어 자바 스크립트.

유효범위

전역변수(local) 지역변수(global)


위의 코드에 대해서 var이 있는 상태로 출력을 하면 global이 나오지만 var이 없는 상태로 하면 local이 나오게 된다. 어째서인가??

var은 기본적으로 코드를 로컬(지역변수)로 저장. 따라서 전역 변수 global이 있고 지역변수 local이 따로 있는 상태가 됨.

그러나var이 없으면 전역변수의 값을 직접 바꾸는 것이 되어 전역변수가 local로 바뀐다.


그렇다면 두개의 방법을 이렇게 병렬하면??
여전히global로 출력이 된다.

앞선 코드로 인해 로컬 변수가 만들어지고 뒤의 값은 로컬 변수가 있는지를 먼저 체크하므로 만들어진 로컬 변수 값을 바꾸기 때문에 이후 호출되는 전역변수 값이 바뀌지 않는 것.


위의 함수에서 var값이 없으면 전역변수 값이 0으로 고정되어서 아래의 for문이 조건을 만족하지 못해 무한 반복하여 페이지가 다운된다.

자바스크립트는 함수에 대한 유효범위 만을 제공한다(다른 언어들은 블록 단위로 준다.)

이러한 유효범위를 정적 유효범위(함수 선언 시점에서의 범위)(static scoping)이라 한다.

전역변수 i=5 지역변수 i =10이 있는데 b함수를 a함수 안에서 호출하면.
지역변수 10이 아니라 전역변수 값 5가 출력된다.

함수 b가 선언된 시점의 전역변수가 나오는 것이지 함수가 호출된 시점에 파악가능한 지역변수가 나오는 게 아니므로

이처럼 호출될떄마다 접근가능한 변수를 부르는 게 아니라(동적 유효범위) 선언된 시점에 접근한 전역변수를 가져오므로 정적 유효범위라 한다.

자바스크립트에서는 함수도 값이다
function a(){} === var a= function(){}

함수a는 변수a에 담겨진 값이다.
a = {
b:function(){}
};
이렇게 표현할 수 있으며 이렇게 객체의 속성값으로 쓰이는 함수를 메소드(method)라 한다.
b는 key라고 하며 속성(프로퍼티)라고도 한다.

업로드중..

함수는 값, 다른 함수의 인자로 사용가능.

함수는 함수의 리턴 값으로도 사용할 수 있다.

'''
function cal(mode){
var funcs = {
'plus' : function(left, right){return left + right},
'minus' : function(left, right){return left - right}
}
return funcs[mode];
}
alert(cal('plus')(2,1));
alert(cal('minus')(2,1));
'''

리턴값 자체에 함수를 넣어놓았다.

배열의 값으로도 사용할 수 있다.
업로드중..

값은 11, 121 , 60.5로 나온다.

이처럼 함수는 변수, 매개변수, 리턴값등으로 사용될 수 있다.

콜백

함수의 인자가 함수인 경우.

function sortNumber(a,b){
// 위의 예제와 비교해서 a와 b의 순서를 바꾸면 정렬순서가 반대가 된다.
return b-a;
}
var numbers = [20, 10, 9,8,7,6,5,4,3,2,1];
alert(numbers.sort(sortNumber)); // array, [20,10,9,8,7,6,5,4,3,2,1]

위에서 넘버 배열에 대해 sort(정렬)을 진행할때 그냥 진행하는 것이 아니라 함수 function을 인자로 받았으므로 함수가 정렬의 기준이 된다.

여기서 잠깐!! sort는
arrayobj.sort(sortFunction)로 sortFunction 인수에 함수를 지정하면 아래의 값 중 하나가 반환된다.

첫 번째 인수가 두 번째 인수보다 작을 경우 - 값
두 인수가 같을 경우 0
첫 번째 인수가 두 번째 인수보다 클 경우 + 값

그러므로 위처럼 b-a값을 리턴하면 큰값이 앞으로 오면서 결과적으로 배열이 정렬되는 것이다.

여기서 sortfunc함수가 콜백 함수가 되며 sort함수는 내부적으로 콜백함수를 호출받으므로 이걸 변경할 수 있다.

즉 sort 함수의 작동방식을 sortfunc함수를 바꿈으로서 바꿀 수 있다.(콜백.)

비동기 처리에서의 콜백

Ajax에서 사용
서버와 웹브라우저 간의 긴밀한 연결, 웹브라우저가 단순한 문서에서 벗어나 애플리케이션으로 발전하는 기술이다.

클로저

내부함수가 외부함수의 맥락에 접근할 수 있는 것.

 function outter(){
    var title = 'coding everybody';  
    function inner(){        
        alert(title);
    }
    inner();
}
outter();

내부함수 inner는 외부함수 outter의 지역변수 title을 호출할 수 있다,

function outter(){
    var title = 'coding everybody';  
    return function(){        
        alert(title);
    }
}
inner = outter();
inner();

함수를 리턴하고 있다
outter 외부함수를 실행한 결과는 inner라는 변수에다가 함수를 넣는 것이 된다. 이후 inner를 실행하면 외부함수에서 정의한 함수가 실행된다.
외부함수는 죽었는데 내부함수가 실행되고 이미 종료된 외부함수 안의 지역변수에 접근을 시도하고 이게 성공하는 상황.

private variable 비밀변수?

정보를 아무나 수정하지 못하게 만듬.

function factory_movie(title){
    return {
        get_title : function (){
            return title;
        },
        set_title : function(_title){
            title = _title
        }
    }
}
ghost = factory_movie('Ghost in the shell');
matrix = factory_movie('Matrix');
 
alert(ghost.get_title());
alert(matrix.get_title());
 
ghost.set_title('공각기동대');
 
alert(ghost.get_title());
alert(matrix.get_title());

실행결과는 Ghost in the shell -> Matrix -> 공각기동대 -> Matrix

  1. 클로저는 객체의 메소드에서도 사용할 수 있다. 위의 예제는 함수의 리턴값으로 객체를 반환하고 있다. 이 객체는 메소드 get_title과 set_title을 가지고 있다. 이 메소드들은 외부함수인 factory_movie의 인자값으로 전달된 지역변수 title을 사용하고 있다.

  2. 동일한 외부함수 안에서 만들어진 내부함수나 메소드는 외부함수의 지역변수를 공유한다. 17행에서 실행된 set_title은 외부함수 factory_movie의 지역변수 title의 값을 '공각기동대'로 변경했다. 19행에서 ghost.get_title();의 값이 '공각기동대'인 것은 set_title와 get_title 함수가 title의 값을 공유하고 있다는 의미다.

  3. 그런데 똑같은 외부함수 factory_movie를 공유하고 있는 ghost와 matrix의 get_title의 결과는 서로 각각 다르다. 그것은 외부함수가 실행될 때마다 새로운 지역변수를 포함하는 클로저가 생성되기 때문에 ghost와 matrix는 서로 완전히 독립된 객체가 된다.

  4. factory_movie의 지역변수 title은 2행에서 정의된 객체의 메소드에서만 접근 할 수 있는 값이다. 이 말은

    title의 값을 읽고 수정 할 수 있는 것은 factory_movie 메소드를 통해서 만들어진 객체 뿐이라는 의미다. JavaScript는 기본적으로 Private한 속성을 지원하지 않는데, 클로저의 이러한 특성을 이용해서 Private한 속성을 사용할 수 있게된다.

클로저 응용

var arr = []
for(var i = 0; i < 5; i++){
arr[i] = function(){
return i;
}
}
for(var index in arr) {
console.log(arrindex);
}
실행 결과는 55555

i값은 외부변수의 값이 아니므로 접근이 안된다.
외부함수의 지역변수값을 내부함수가 참조하도록 하려면.
함수를 하나더 적어넣어 외부함수로 만들고 이를 호추한다.

위의 식을 제대로 고치면.

var arr = []
for(var i = 0; i < 5; i++){
arr[i] = function(id) {
return function(){
return id;
}
}(i);
}
for(var index in arr) {
console.log(arrindex);
}

id라는 매개변수로 i값을 전달하고 있으며 이렇게 되면 내부함수는 외부함수의 지역변수인 id를 쓰고 있으므로 정상적으로 작동된다.
즉 id라고 하는 지역변수를 만들어 i값을 전달받는 것으로 외부함수 내부함수의 관계를 만든 것.

실행결과는 012345

  1. 유효범위: 정적 유효범위(선언 시점)를 가진다.
  2. 콜백 : 함수의 인자로 함수를 호출해서 작동방식을 바꿈.
  3. 클로저: 내부함수가 외부함수의 맥락에 접근할 수 있는 것.

    profile
    왕초보

    0개의 댓글

    관련 채용 정보