https://help.github.com/articles/adding-an-existing-project-to-github-using-the-command-line/




제목: Inside Javascript

지은이: 송형주, 고현준


우선 저는 C++, C#을 주로 사용하다가 최근에 javascript를 공부하며 이것 저것 만들어보고 있는 사람입니다.

자바스크립트를 시작할 때 책 조금 훑어보고, 인터넷 찾아보며 개발을 하였습니다.

내심 C++에 비하면 자바스크립트는 뭐 아무것도 아니지 이런 생각이 있었던 것 같습니다. 개발을 하면서 기본적인 원리와 개념에 대한 이해가 부족해서 알고있는 방법으로만 자꾸 로직을 짜게되는 것 같아서 Inside Javascript를 보게되었습니다.


결론부터 말하자면 최고입니다!!

*프로그래밍을 javascript로 처음 접하는 분들에게는 권하지 않습니다. oop, c++등을 알고 있다는 가정하에 설명하는 부분이 상당히 있습니다.


클로저와 프로토타입, 함수 호이스팅등 자바스크립트의 주요 개념에 대해서 원리 부터 내부적으로 어떻게 동작하는지 추상적으로 알 수 있게끔 잘 설명이 되어 있습니다.


그리고, 말 그대로 javascript의 내부 코드를 그대로 구현해보는 예제들이 꽤 수록되어 있습니다. 개념을 배우고 이 개념이 javascript 혹은 라이브러리에는 어떻게 쓰여있는지 소스코드를 통해 확인할 수 있습니다.



책을 보고 느낀 점은 "javascript 재밌다!"와 "나 진짜 모르면서 했구나..." 입니다. javascript 너무 안일하게 봤었던 것 같습니다.

무미 건조하게 javascript를 사용했었는데 클로저와 this binding등을 통해서 새로운 방식으로 프로그래밍을 할 수 있을 것 같습니다. 


여지껏 사용할 때 C++로 개발할 때 했던 방식에 최대한 맞춰서 oop를 흉내내곤 했었는데 좀 다르게 사용해보고 싶어지네요.


좋은책입니다.










인사이드 자바스크립트를 공부하며 정리하는 포스팅입니다.



함수형 프로그래밍은 프로그래밍의 여러 가지 패러다임 중 하나이다. 함수의 조합으로 작업을 수행하는 프로그래밍 방식이다. 중요한 것은 이 작업이 이루어 지는 동안 작업에 필요한 데이터와 상태는 변하지 않는다는 점이다. 변할 수 있는 건 오직 함수 뿐이다. 


자바스크립트에서의 함수형 프로그래밍은 다음과 같은 자바스크립트의 특징 때문에 가능하다.

- 일급 객체로서의 함수

- 클로저



1.Memoization Pattern


//Memoization이란 계산 결과를 저장해 놓아 이후 다시 계산할 필요 없이 사용할 수 있게 한다는 컴퓨팅 용어이다.
//말 그대로 함수의 키값에 결과를 저장해두고 이후 계산없이 사용할 수 있다.
//왠지 아래 함수보다는 input, func 값으로 key값을 만들어서 하면 이후 똑같은 호출 시 계산없이해서 좋을 거 같다.
//jQuery에서는 data()라는 메서드로 이 메모이제이션 패턴을 사용하였다.

function Calculate(key, input, func){
    Calculate.data = Calculate.data || {};
    if(!Calculate.data[key]){
        var result;
        result = func(input);
        Calculate.data[key] = result;
    }
    return Calculate.data[key];
}

var result;

result = Calculate(1,5,function(input){
    return input * input;
});
console.log(result);

result = Calculate(2, 5, function(input){
    return input * input /4;
});
console.log(result);

console.log(Calculate(1));
console.log(Calculate(2));



1) Memoization을 적용한 Factorial


//클로저를 활용한 앞서 실행한 factorial 값을 저장하는 factorial 함수
var factorial = function(){
    var cache = {'0':1};
    //연산을 수행하는 과정에서 캐시에 저장된 값이 있으면 곧바로 그 값을 반환한다.
    var factorial = function(n){
        var result = 0;
        if(typeof(cache[n]) === 'number'){
            result = cache[n];
        } else {
            result = cache[n] = n * factorial(n-1);
        }
        return result
    };

    return factorial;
}();

console.log(factorial(10));
console.log(factorial(12));



2) Memoization을 적용한 Fibonaci


//메모이제이션 기법을 적용한 피보나치 수열

var fibo = function(){
    var cache = {'0' : 0, '1': 1};

    var fibo = function(n){
        if(typeof(cache[n]) === 'number'){
            result = cache[n];
        } else {
            result = cache[n] = fibo(n-1) + fibo(n-2);
        }
        return result;
    }
    return fibo;
}();

console.log(fibo(10));


2.함수 적용

apply(), bind(), call() 함수는 함수형 프로그래밍에서 중요한 함수들이다.




3.Currying


커링이란 특정 함수에서 정의된 인자의 일부를 넣어 고정시키고, 나머지를 인자로 받는 새로운 함수를 만드는 것을 의미한다.

function calculate(a, b, c){
    return a*b+c;
}

function curry(func){
    var args = Array.prototype.slice.call(arguments, 1);

    return function(){
        return func.apply(null, args.concat(Array.prototype.slice.call(arguments)));
    }
}

var new_func1 = curry(calculate, 1);
console.log(new_func1(2,3)); //5 

var new_func2 = curry(calculate, 1, 2);
console.log(new_func2(3));//5

커링이란 특정 함수에서 정의된 인자의 일부를 넣어 고정시키고, 나머지를 인자로 받는 새로운 함수를 만드는 것을 의미한다.


bind() 함수가 커링과 매우 유사하다.


//bind() 함수는 고정시키고자 하는 인자를 함수 호출시 전달하고, 반환받은 함수를 호출하면서 나머지 가변 인자를 넣어줄 수 있다.

Function.prototype.bind = function(thisArg){
    var fn = this;
    slice = Array.prototype.slice;
    args = slice.call(arguments, 1);
    return function(){
        return fn.apply(thisArg, args.concat(slice.call(arguments)));
    };
}


4.wrapper


특정 함수를 자신의 함수로 덮어쓰는 것을 말한다. 물론 여기서 사용자는 원래 함수 기능을 잃어버리지 않은 상태로 자신의 로직을 수행할 수 있어야 한다.

기존 제공하는 함수에 기능을 추가하고 싶거나, 버그를 피하고자 할 때 많이 사용된다.


function wrap(object, method, wrapper){ var fn = object[method]; return object[method] = function(){ //original에서의 this와 익명함수 wrapper에서의 this가 다르므로 동일하게 만든다. return wrapper.apply(this, [fn.bind(this)].concat(Array.prototype.slice.call(arguments))); }; }

//original 함수가 있고, 이는 인자로 넘어온 값을 value에 할당하고 출력하는 기능을 한다. Function.prototype.original = function(value){ this.value = value; console.log("value : " + this.value); } //이를 사용자가 덮어쓰기 위해 wrap 함수를 호출하였다. 세 번째 인자로 넘긴 자신의 익명 함수를 original에 덮어쓰는 것이다. //여기서 사용자는 자신의 익명 함수의 첫 번째 인자로 원래 함수의 참조를 받을 수 있다. 이로 인해 원래 로직을 수행 할 수 있다. var mywrap = wrap(Function.prototype, "original", function(orig_func, value){ orig_func(value); console.log("wrapper value : " + this.value); }); var obj = new mywrap("song");