---
description: Node.js로 구현하는 쇼핑몰 프로젝트 3회차 수업 요약 내용입니다.
---

# 3회차

## 즉시 실행 익명 함수 (immediately-invoked function expression)

* 함수 선언 + 함수 실행
* 외부에서 내부 변수에 접근하지 못하게 하기 위해
* 함수 실행 후 return 문으로 내가 원하는 변수만 제공가능

```javascript
function test(){
    console.log("my test");
}
test();
```

```javascript
(function(){
    console.log("my test");
})();
```

```javascript
// 외부 변수에 영향 받지 않는 예

var test = 20;
(function(){

    var test = 10;
    console.log(test); // ??

})();

console.log(test); // ??
```

```javascript
// 필요한 변수만 받는법
var test = (function(){
    var a = "1";
    return {
        b  : "2",
        c : "3"
    };
})();
console.log(test.a); //undefined
console.log(test.b);
```

```javascript
// 네임 스페이스
(function($){

})(jQuery);


(function(d){  //d로 document 객체 사용
    d.write('document 작성');
})(document); //doment객체를 인자로 넘긴다
```

### 콜백패턴

실행되는 것을 목적으로 다른 오브젝트의 메소드에 전달되는 오브젝트를 말한다.

특정 로직을 담은 메소드를 실행 시키기 위해 사용하는데, 자바에선 메소드 자체를 파라미터로 전달할 방법은 없기 때문에 메소드가 담긴 오브젝트를 전달해야 한다.

그래서 펑셔널 오브젝트(functional object)라고도 한다.

```javascript
// 함수가 끈나고 인자로 받은 함수를 실행
// 간단히 만들어보기

function test(name, title , callback){
    this.name = name;
    this.title = title;
    console.log('call function!');
    callback();
}

test( "haha" , "kkk" , function(){
    console.log('call callback');
});   //익명함수로 호출함
```

```javascript
// 인자를 넣어서 사용해보기

function test(name, title , callback){
    this.name = name;
    this.title = title;
    console.log('call function!');
    callback("11111");
}

test( "haha" , "kkk" , function( firstArg ){
    console.log(firstArg);
});
```

```javascript
// arguments 변수
// 함수안의 정해지지 않은 개수의 인수를 받을 수 있음. 
function test(name, title , callback){
    this.name = name;
    this.title = title;
    console.log('call function!');
    callback(1,2,3,4,5,6);
}

test( "haha" , "kkk" , function(){   //호출인자를 받는다
    for(var i=0 ; i<arguments.length ; i++){
        console.log(  i+1 + "번째 = " +  arguments[i]);
    }
});
```

```javascript
// 익명함수가 아닌 일반 함수로 받기

function test(name, title , callback){
    this.name = name;
    this.title = title;
    console.log('call function!');
    callback(1,2,3,4,5,6);
}
function outCallBack(){
    console.log('outer callBack');

}
test( "haha" , "kkk" , outCallBack );
```

### 메서드 체이닝

메서드가 객체를 반환하게 되면, 메서드의 반환 값인 객체를 통해 또 다른 함수를 호출할 수 있다. 이러한 프로그래밍 패턴을 메서드 체이닝 (Method Chaining) 이라 정의한다.

```javascript
function a(){
    console.log('a call');
    return this;
}
function b(){
    console.log('b call');
    return this;
}
a().b();
```

응용 예제

[https://nodejs.junyoung.me/method-chaining/](https://nodejs.junyoung.me/method-chaining/)

### Prototype

JavaScript는 클래스라는 개념이 없다. 그래서 기존의 객체를 복사하여(cloning) 새로운 객체를 생성하는 프로토타입 기반의 언어이다. 프로토타입 기반 언어는 객체 원형인 프로토타입을 이용하여 새로운 객체를 만들어낸다. 이렇게 생성된 객체 역시 또 다른 객체의 원형이 될 수 있다. 프로토타입은 객체를 확장하고 객체 지향적인 프로그래밍을 할 수 있게 된다. 프로토타입은 크게 두 가지로 해석할 수 있다. 프로토타입 객체를 참조하는 prototype 속성과 객체 멤버인 proto 속성이 참조하는 숨은 링크가 있다. 이 둘의 차이점을 이해하기 위해서는 JavaScript 함수와 객체의 내부적인 구조를 이해 해야한다.

```javascript
// prototype 은 공유하는 객체
function Car(){ }
var myCar1 = new Car();
var myCar2 = new Car();
Car.prototype.color ="red";
console.log(myCar1.color);
console.log(myCar2.color);
Car.prototype.color ="blue";
console.log(myCar1.color);
console.log(myCar2.color);

function Car(){}
var myCar1 = new Car();  //Car의 prototype을 참조함
var myCar2 = new Car();  //Car의 prototype을 참조함
var myCar3 = new Car();  //Car의 prototype을 참조함

Car.prototype.color = "red";
console.log(myCar1.color);
console.log(myCar2.color);
console.log(myCar3.color);
//myCar1, myCar2, myCar3이 같은 protype을 참조하므로 
red 출력
```

```javascript
// new 또는 객체가 생성 될 때 참조할 수 있다.
var test = { aa : 111 }; //리터럴로 객체생성
test.prototype.bb = 222; //문법에러
console.log(test.bb);
```

```javascript
// property 출력해보기
function Car(){
    this.name = "첫번째";
    this.title = "타이틀"
}
Car.prototype.pro1 = "val1";
Car.prototype.pro2 = "val2";
var myCar = new Car();
var myCar = new Car();
var prop;
for(prop in myCar){
    if(myCar.hasOwnProperty(prop)){
        console.log(prop + " = "+ myCar[prop]);
    }
}
```

### Object.create()

* 객체 생성
* new 키워드가 Java와 비슷하고, 자바스크립트 프로토타입 기반 프로그래밍 ([https://ko.wikipedia.org/wiki/프로토타입\_기반\_프로그래밍](https://ko.wikipedia.org/wiki/%ED%94%84%EB%A1%9C%ED%86%A0%ED%83%80%EC%9E%85_%EA%B8%B0%EB%B0%98_%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%B0%8D)) 과 맞지 않다고, Object.create() 선호
* 필드는 필드 따로, 공유하는 부분은 prototype으로 처리

```javascript
// Brower support IE8이하
if (!Object.create) {
     Object.create = function (o){ 
         function F() {}
         F.prototype = o; 
         return new F();
     }
}
```

```javascript
// 변수 접근
function Car(){
    this.name = "내차";
    this.title = "타이틀"
}
Car.prototype.move = function(){
    console.log(this.name + " 이동" );
};

var myCar = Object.create(Car.prototype);
myCar.move();  //undefined
```

```javascript
// Object.create로 생성시 prototype공유하고 필드로 접근가능
// 두번째 인자에 접근 가능하게 설정

function Person(){
    this.name = "hello";
}
Person.prototype.speack = function(){
    console.log(this.name + " speack");
};
var myMan = Object.create(Person.prototype , {
    name : {
        value : "myMan",   //초기 값 설정
        writable : true   //쓰기가능 속성설정
    }
});
myMan.speack();

var myMan = Object.create(Person.prototype);
Object.defineProperties(myMan ,{
    name : {
        value : "myMan",
        writable : true
    }
});
myMan.speack();

Object.defineProperty = 단일 속성 설정
Object.defineProperties = 복수 속성 설정
```

## MongoDB 란?

* json-style의 document형태로 저장하는 오픈소스 NoSQL 데이터 베이스 (C++로 작성)

### 문서지향 데이터베이스

행 개념 대신에 보다 유연한 모델인 문서를 이용하는데, 내장 문서와 배열따위의 표현이 가능해서 복잡한 객체의 계층 관계를 하나의 레코드(열)로 표현할 수 있다. 이것은 자바나 파이썬 같은 최신 객체지향 언어들을 사용하는 개발자에 매우 편리함을 가져다 준다.

### 스키마

몽고 디비의 특징 중 가장 유명한 것은 스키마가 없다는 것이다. 이것은 필요할 때 마다 필드를 추가하거나 제거하는 것이 매우 쉬워졌음을 의미한다. 사실은 필드라는게 없는거나 마찬가지니까. 따라서 개발 과정이 매우 단순해지고 빠르게 개발이 가능하게 된다.

### RDB와 비교

| RDBMS       | MongoDB            |
| ----------- | ------------------ |
| Database    | Database           |
| Table       | Collection         |
| Tuple / Row | Document           |
| Column      | Key/Field          |
| Table Join  | Embedded Documents |
| Primary Key | ObjectID           |

### 빅데이터 처리 특화

Memory Mapped(데이터 쓰기 시에 OS의 가상 메모리에 데이터를 넣은 후 비동기로 디스크에 기록하는 방식)를 사용하기 때문에 방대한 데이터를 빠르게 처리할 수 있다. 하지만 OS의 메모리를 활용하는 만큼, 메모리가 가득 찰 시 하드디스크로부터 데이터를 처리하게 되어 속도가 급격히 느려지게 된다.

### 쿼리 지원

기존의 NO-SQL들이 key,value의 형태만 제공하는 것과 달리 RDB와 같이 쿼리를 사용할 수 있습니다. 이를 통해 효과적으로 데이터를 추출해낼 수 있고, 기존의 관계형 데이터베이스로부터의 이전이 쉽습니다.

### 대규모 분산 시스템 구성 지원

관계형데이터베이스에 비해 대규모 분산 시스템 구성을 쉽게 할 수 있도록 연결되지 않은 데이터들이 동시 병렬 처리가 가능한 MapReduce 자동으로 데이터를 여러서버에 분할시켜주는 Auto-Sharding 데이터 유실을 대비한 Replica 기능을 제공합니다.

## 단점

### key 중복 입력의 비효율성

birthday key에 해당하는 데이터를 10000개를 넣을 경우, DB에는 10000번의 "birthday"가 함께 저장된다.

{birthday:19920101} {birthday:19000202} {birthday: 18880303} 중복된 key값이 계속 들어가기 때문에, 비효율적인 저장이 될 수 밖에 없다.

### Memory Mapped의 메모리 제약 (빅데이터 처리 특화 참조)

### 불안전함

데이터의 양이 많을 경우 몇몇 데이터가 날아간다던가, 샤딩이 정상적으로 동작을 하지 않는다던가.. 레플리카 프로세스가 좀비가 된다던가.. 등등의 다양한 에러가 존재한다.

## Robomongo 설치

## 연습
