JavaScript
다시 시작하기

앞에 서있는 사람은?

이 발표 자료는?

시작하기 전에...

학생들에게 물어본 JavaScript

  • Web Browser에서 동작한다.

  • 웹페이지의 동적인 부분을 담당한다.

  • 스크립트 언어이다.

  • 형이 없다

  • 컴파일이 안될것 같지만 사실된다.

  • 클래스가 펑션이다.

  • 함수도 변수다.

학생들에게 물어본 JavaScript

  • 핫하다. 다 된다. 모른다.

  • 자바랑 비슷할 것 같다.

  • 자바에 묻어갈려는 언어다

  • ==도 있고 === 도 있다.

  • 그때그때 다르다.

  • XX 어렵다.

  • XX 못해 먹겠다.

ㅂㄷㅂㄷ

왜  이럴까...?

학생들이 많이 접하는 JavaScript

  • jQuery

  • Angular

  • Copy & Paste

하지만...

  • JavaScript 언어 자체에 집중하는 경우는 드뭅니다.
     
  • JavaScript 그 자체를 잘 익혀야 활용도 잘 합니다.

JavaScript

Java와 아무런 연관이 없음

쓰이는 곳

  • Web Bowser
  • Node.js #
  • Unity
  • MongoDB #
  • Flash
  • 기타 등등...

왜 쓰는가?

  • 과거 : 웹페이지를 좀 동적으로 만들어 볼려고
  • 현재 : 언어가 있기에 쓴다.

JavaScript?

This is not JavaScript!

CSS가 발전 하지 않았을때에는...

  • Java Applet
  • Flash
  • JavaScript

But Now...

디자인 요소(view)

행동, 데이터(model)

HTML/CSS

JavaScript

Unity

Canvas

WebGL

#

##

JavaScript로 뭔가를 만들면.. 

var player = get("#player");
var playButton = get("#play");
var stopButton = get("#stop");

playButton.on("click", function(){
  player.play();
});
stopButton.on("click", function(){
  player.pause();
});

function get(){
    document
        .querySelector
        .apply(document, argument);
}
playButton.on("click", function(){
    player.play();
});
player.on("end", function(){
    endMessage.show();
});
capture.on("saved", function(img){
    privews.add(img);
});
server.on("uploaded", function(){
    //...
});

Event

EventHandler

Event Driven

  • Click하면 재생한다.
  • 비디오가 끝나면 글을 보여준다.
  • Caputer가 저장 되면 preview를 추가한다.

~하면 ~한다.

왜 이렇게 했을까?

본디 사람은...

  • 배가 고프면 음식을 먹는다.
  • 지하철이 도착하면 지하철에 탄다.
  • 전화벨이 울리면 전화를 받는다.

~하면 ~한다.

사람의 생각과 유사한

병렬 처리 방법

대기시간이 길어지면

그사이를 못참고 다른일한다.

Async Job

종료가 되기를 기다리지 않고
바로 다음 작업을 한다.

var req = new Request();

req.send({value : 123}); //not wait!

req.on("response", function(){
    console.log("recived");
});

console.log("sent");
sent
recived
var server = new Server(url);

var time = new BigText();
time.text = "Ready";

var start = new Button("Start");
var stop = new Button("Stop");

var timer = new Timer();
timer.displayTo(time);
start.on("click", function(){
    timer.start();
});
stop.on("click", function(){
    timer.stop();
});

또다른 예제

var server = new Server(url);

var time = new BigText();
time.text = "Ready";

var start = new Button("Start");
var stop = new Button("Stop");

var timer = new Timer();
timer.displayTo(time);
start.on("click", function(){
    timer.start();
});
stop.on("click", function(){
    timer.stop();
});

많이 봤던 익숙함

객체지향

var a = 1;
var str = "abcd";
var numbers = [1, 2, 3];
var slides = [
    {title: 'Looking Ahead'},
    {title: 'Forecast'},
    {title: 'Summary'}
];
var func = function(){
}
var time = new Date("2015-8-15");

Object, Number

Object, string

Object, Array

Object, Array

Object

Object

Object

Object, Function

Object, Date

OOP in JavaScript

  • Class는 없음
  • 상속 있음. (prototype chain)
  • 다형성 있음. (duck typing)

방식이 다를뿐 엄연한 객체지향적 언어이다.

하나 하나 배워봅시다.

변수

변수

  • var로 선언한다.
  • 변수에는 Type이 없다.
  • Type
    • Number
    • String
    • Boolean
    • Object
    • Array
    • Function
    • undefined, null, NaN
  • 이 모든 타입을 var로 선언된 변수안에 담을수 있다.
var a; //undefined
a = 1; //Number
a = "abc"; //string
a = []; //Array
a = {}; //Object
a = function(){ 
    //Function
}
a = null; // null
var a; //undefined
console.log(a);
a = 1; //Number
console.log(a);
a = "abc"; //string
console.log(a);
a = [1,2,3]; //Array
console.log(a);
a = {}; //Object
console.log(a);
a = function(){ 
    //Function
}
console.log(a);
a = null;
console.log(a);

특수형

  • undefined
    • 정의되지 않았음
  • null
    • 정의는 되었는데 값이 없음
  • NaN
    • 숫자가 아님
    • 123/0
       
  • Boolean식에서는 
                              false로 간주 
if(undefined){
    console.log("undefined");
} else if (null) {
    console.log("null");
} else if (NaN) {
    console.log("NaN");
} else {
    console.log("false!");
}

notNull = nullable || {};

Array

Array

  • 가변형 길이
  • 내부에는 어떤 Type의 값이라도 들어갈수 있다. 
  • .length
    • 길이가 즉각적으로 반영
    • 배열을 길이 조정 가능
var arr = [];
console.log(arr, arr.length);
arr[0] = 1;
console.log(arr, arr.length);
arr.length = 3;
console.log(arr, arr.length);
arr[0] = 123;
arr[1] = "abc";
arr[2] = new Date();
console.log(arr);
arr.length = 1;
console.log(arr, arr.length);
arr[5] = "?";
console.log(arr, arr.length);

Array

  • 수많은 내장 함수
    • push / pop
    • unshift / shift
    • forEach
    • map / reduce
    • filter / some / all
    • ...
  • 거의 모든 선형 자료구조를 Array로 표현
var stack = [];
stack.push(1);
stack.push(2);
console.log(stack);
var value = stack.pop();
console.log(stack, value);

var queue = [];
queue.push(1);
queue.push(2);
console.log(queue);
var value = queue.unshift();
console.log(queue, value);

제어문

if, for, while

  • C, Java와 동일
  • 단, 변수의 범위가 블록안으로 제한되지 않는다.
var a = 15;
if(a > 10){
    console.log("lt 10")
} else if(a > 20){
    console.log("lt 20")  
} else {
    console.log("else")
}

console.log("for");
for (var i = 0; i < 10; i++){
    console.print(i);
}
console.log(i);

console.log("while");
while(i > 0) {
    console.print(i);
    i--;
}

switch

  • case에는  문자, 숫자, 문자열
  • break를 쓰지않으면 다음으로 넘어간다.
var input = new Input();
new Button("send").on("click", function(){
    switch(input.text){
        case 'a':
            console.log("a");
            break;
        case 9:
            console.log("9");
            break;
			
        case "red":
            setBackground("red");
            break;
        case "blue":
            setBackground("blue");
            break;
        default: 
            console.log("default");
    }
});

Object

Object

  • 세상에서 가장 쉬운
    객체 만들기 방법
  • Key - Value의 집합
    • 추후 추가 가능
    • 편집 가능
    • Key - 문자열
    • Value - 모든 형 가능
var obj = {};
obj.hello = "world";
console.log(obj);

var slide = {
    name : "javascript",
    url : "wikinote.bluemir.me",
    tags : ["javascript", "easy"]
};
console.log(slide.name);
console.log(slide["url"]);

Function

JavaScript의 핵심 중 하나!

#

Function

  • return value와 parameter에 type이 없다.
  • 변수에 담길수 있다.
    • parameter로 전달될수 있다.
    • 함수는 객체
    • 일급 객체 #
  • 변수의 범위는 함수이다. #
function add(a, b) {
    return a + b;
}
var sub = function(a, b){
    return a - b;
}
function execute(func, a, b){
    return func(a, b);
}
console.log(add(3, 5));
console.log(sub(8, 3));
console.log(execute(add, 2, 5));

Function

  • 객체에 쓰기
  • "this"
    • C++, Java와는 다르다.
    • execution context #
    • 함수가 호출될때 결정된다.
    • 언제든 임의로 바뀔수 있다.
var someone = {
    getName : function(){
        return this.name;
    },
    name : "아이유"
};
console.log(someone.getName());

"this"

  1. 기본적으로 글로벌 변수

  2. 함수 호출시 마지막 점(.) 바로 앞에 것

  3. call, apply, bind된 함수만
    예외적으로 첫번째 인자.

var obj = {
    func : function(){
        console.log(this.str);
    },
    str : "a"
}
var otherobj = {
    str : "b"
}
this.str = "c"
obj.func(); // a
obj.func.call(otherobj); // b
obj.func.apply(otherobj); // b
val = obj.func;
val(); //c
val = obj.func.bind(obj);
val(); //a



생성자

  • 대체 저기에 new는 무엇이죠?
  • 마치 클래스 처럼 보이는 데...
  • 함수 앞에 new를 붙이면 생성자로써 동작함.
var server = new Server(url);

var time = new BigText();
time.text = "Ready";

var start = new Button("Start");
var stop = new Button("Stop");

var timer = new Timer();
timer.displayTo(time);
start.on("click", function(){
    timer.start();
});
stop.on("click", function(){
    timer.stop();
});

new

  • new 로 객체를 만들면 
    • 일정한 형식을 가진 객체를 빨리 만들수 있다.
    • 여러객체들이 한 함수를 돌려 쓸수 있다. 
function People(name){
    this.name = name;
}
People.prototype.getName = function(){
    return this.name;
}
var person = new People("아이유");
console.log(person.name);
console.log(person.getName());

prototype

  • 같은 생성자로 생성된 여러 객체들이 공유하는 함수 집합체
  • 함수를 찾는 방법
    • prototype chainning
  • JavaScript의 객체 지향 방법

함수 안에 함수

  • 내부에서 선언된 함수는 선언될 당시에 외부 함수의 변수에 접근할수 있다.
  • 이때 inner 함수를 Closure라고 부른다. 
  • 선언될 당시의 변수를 참조 하므로 조심해야 한다.
var inner;
function foo() {
    var bar = "foo";
    inner = function (){
        console.log(bar);
    }
}
function test(){
    var bar = "test";
    inner();
}	
foo(); 
test();

더 다루고 싶은 주제는
산더미 같지만...

  • Closures # # #

  • Execution Context # #

  • Object Oriented Programming
                                     in JavaScript # # #

  • Promise (Q) # # #

  • Functional Programming #

  • ...

만들어 볼까요?

실습에 앞서

오늘 실습에서는...

  • HTML을 배제하고 JavaScript만 사용합니다.

  • 여러분의 편의를 위하여 Library를 작성했습니다.
    다른 곳에서 왜 안되냐고 묻지 마세요.

  • 혹시 궁금한 사람은 링크 참조

오늘의 과제 #1

스톱워치

  • Start 버튼을 누르면 시작한다.

  • Stop 버튼을 누르면 지난 시간을 표시 한다.

Text 출력

  • JavaScript의 변수 선언
    • var <변수 이름>;
  • new BigText();
    • 큰글씨 출력용 객체
var time = new BigText();

time.text = "Ready";

Button

  • new Button(name);
    • 새로운 버튼 만들기
  • button.on(event, func)
    • 버튼이 눌렸을때 실행될 함수 지정
    • eventHandler, callback
var time = new BigText();

time.text = "Ready";

var start = new Button("Start");
var stop = new Button("Stop");

start.on("click", function(){
    time.text = "Start!";
});
stop.on("click", function(){
    time.text = "Stop!";
});

Timer

  • timer.start() / timer.stop()
    • Timer를 시작 / 종료
  • timer.displayTo(element)
    • 해당 요소에 시간 표시
var time = new BigText();

time.text = "Ready";

var start = new Button("Start");
var stop = new Button("Stop");

var timer = new Timer();
start.on("click", function(){
    timer.start();
});
stop.on("click", function(){
    timer.stop();
});
timer.displayTo(time);

오늘의 과제 #2

스톱워치 온라인

  • 10초를 맞추기 게임!

  • 랭킹제출

  • top 10 받아오기

랭킹 받아 오기

서버를 만들어야 하는데

             시간이 너무 오래 걸려서...

미리 만들어 왔어요!

서버코드...도 JavaScript!

var express = require("express");
var bodyParser = require('body-parser')
var nedb = require("nedb");

var app = express();
var db = new nedb();

db.ensureIndex({ fieldName : "dTime", unique : false }, function(err){
});

app.use(bodyParser.json());

app.use(function(req, res, next){
        res.set({
                "Access-Control-Allow-Origin" : "*",
                "Access-Control-Allow-Headers" : "Origin, Content-Type",
                "Access-Control-Request-Method" : "POST, GET, OPTIONS"
        });
        next();
});

app.get("/api/rank", function(req, res){
        var limit = parseInt(req.query.limit);
        db.find({}).sort({dtime : 1}).limit(10).exec(function(err, docs){
                res.jsonp(docs);
        });
});
app.post("/api/recode", function(req, res){
        var body = req.body;

        db.insert({
                time : body.time,
                dtime : Math.abs(body.time - 10000)
        }, function(err,doc){
                res.jsonp(doc);
        });
});

var server = app.listen(ENV.PORT, function(){
        var host = server.address().address;
        var port = server.address().port;

        console.log('Example app listening at http://%s:%s', host, port);
});

랭킹 받아 오기

  • new Server()
    • 서버 접속 객체 생성
  • server.reciveTop(limit, cb)
    • 서버에서 랭킹 받아오기.
    • 데이터를 모두 받아 오면 callback함수가 호출
var server = new Server("http://timer.bluemir.me/api");

server.reciveTop(10, function(err, data){
    if (err) {
        throw err;
    }
    console.log(data);
});

랭킹 출력 하기

  • data는 배열
  • data의 각 요소는 객체
     
  • 서버에서 주는 이런 데이터 형식을 JSON이라고 한다.
var server = new Server("http://timer.bluemir.me/api");

var list = [];
for(var i = 0;i < 10; i++) {
    list[i] = new Text();
}
server.reciveTop(10, function(err, data){
    if(err) throw err;
    for(var i = 0; i < data.length; i++){
        list[i].text = (i + 1) + ". " + (data[i].time /1000);
    }
});

랭킹 출력 하기

  • new List()
    • 목록을 위한 객체 생성
    • 일일히 Text를 10개씩 
      만들지 않아도 된다.
var server = new Server("http://timer.bluemir.me/api");
var rank = new List();
server.reciveTop(10, function(err, data){
    if(err) throw err;
    for(var i = 0; i < 10; i++){
        data[i] = data[i].time /1000;
    }
    rank.list = data;
});

랭킹 출력 하기

  • [].map
    • 배열의 각 요소마다  
      callback 함수를 호줄해서 내용을 바꾸어 준다.
var server = new Server("http://timer.bluemir.me/api");
var rank = new List();
server.reciveTop(10, function(err, data){
    if(err) throw err;
    rank.list = data.map(function(e){
        return e.time /1000;	
    });
});
var time = new BigText();

time.text = "Ready";

var start = new Button("Start");
var stop = new Button("Stop");

var timer = new Timer();
start.on("click", function(){
    timer.start();
});
stop.on("click", function(){
    timer.stop();
});
timer.displayTo(time);

var server = new Server("http://timer.bluemir.me/api");
var rank = new List();
server.reciveTop(10, function(err, data){
    if(err) throw err;
    rank.list = data.map(function(e){
        return e.time /1000;	
    });
});

기록 전송 하기

  • server.sendRecode(time,cb)
    • 서버에 기록을 보냄
  • refreshRank()
    • Rank 새로 받아오는 함수
    • 이전코드와 반복되어 만든 함수 
//...
stop.on("click", function(){
    server.sendRecord(timer.time(), function(){
        refreshRank();
        time.text = "Saved!";
    });
    timer.stop();
});
function refreshRank(){
    server.reciveTop(10, function(err, data){
        if(err) throw err;
        rank.list = data.map(function(e){
            return (time / 1000) + " : " +  e.dtime + "ms";
        });
    });
}
//...
var time = new BigText();

time.text = "Ready";

var start = new Button("Start");
var stop = new Button("Stop");

var timer = new Timer();
start.on("click", function(){
    timer.start();
});
stop.on("click", function(){
    server.sendRecord(timer.time(), function(){
        refreshRank();
		time.text = "Saved!";
    });
    timer.stop();
});
function refreshRank(){
    server.reciveTop(10, function(err, data){
        if(err) throw err;
        rank.list = data.map(function(e){
            return (e.time / 1000) + " : " +  e.dtime + "ms";
		});
	});
};
timer.displayTo(time);

var server = new Server("http://timer.bluemir.me/api");
var rank = new List();
server.reciveTop(10, function(err, data){
    if(err) throw err;
    rank.list = data.map(function(e){
        return e.time /1000;	
    });
});

var server = new Server("http://timer.bluemir.me/api");
var rank = new List();
refreshRank();

Q & A

Reference

같이 보면 좋은 책 & 사이트