자바스크립트 기초

FE개발랩 김동우

자바스크립트란?

JavaScript

BOM

DOM

ECMAScript

JavaScript == ECMAScript??

OR

JavaScript

  • ECMAScript
    • 언어의 핵심 내용을 정의
    • 문법, 타입, 연산자, 키워드, 객체 등
  • DOM:
    • 문서 객체 모델 (Document Object Model)
    • HTML을 노드의 계층구조로 다룰 수 있게 해주는 API 정의
  • BOM
    • 브라우저 객체 모델 (Browser Object Model)
    • 브라우저 창에 접근하고 조작할 수 있게 하는 API

ECMAScript Edition

  • ES 3: 구형 브라우저에서 지원 (IE8-)
  • ES 5: 모던? 브라우저에서 (일부) 지원 (IE9+)
  • ES 6 (2015)
    • 최신 브라우저에서 일부 지원
    • 트랜스파일러(Babel 등) 필요
    • 최신 버전의 Node.js 에서 지원

브라우저 지원 범위

  • http://caniuse.com/
  • http://kangax.github.io/compat-table/es5/
  • http://kangax.github.io/compat-table/es6/
  • https://developer.mozilla.org/en-US/

Data Types

변수 선언 (var)

// 선언만
var a, b, c;

// 값 할당
var d = 10, 
    e = 20,
    f = 'hello';

// 연산 결과 할당
var g = d + e;

// 기존에 할당된 변수 재정의 가능
var g = 100;
var g = 'hello';

Data Types

Primitive Type

  • Number
  • String
  • Boolean
  • Null
  • Undefined

Object

  • Array
  • Function
  • Date
  • RegExp

typeof

var a;
var b = 1;
var c = true;
var d = 'hello';
var e = [1, 2, 3];
var f = null;

typeof a;  // 'undefined'
typeof b;  // 'number'
typeof c;  // 'boolean'
typeof d;  // 'string'
typeof e;  // 'object'
typeof f;  // 'object'

null vs undefined

  • undefined : 변수가 선언되었지만 값이 할당되지 않은 상태 or 객체가 해당 속성을 갖고 있지 않을 때
  • null  : 변수가 명시적으로 아무 값도 갖고 있지 않음을 뜻함

undefined를 값으로 직접 할당하지 말 것

null vs undefined

var a;
var b = null;
var c = undefined; // (X)

a === b;  // false
typeof a; // undefined
typeof b; // object

// 함수의 인자나 리턴값이 없는 경우
function test(a) {
  console.log(a); // undefined
}
var result = test();
console.log(result); // undefined

// 객체의 프로퍼티가 없는 경우
var obj = {};
console.log(obj.something); // undefined



Number

  • 정수 / 실수의 구분이 없음
  • IEEE-754 (Double-precision Floating-point 64bit)
typeof 1;       // number 
typeof 0.1;     // number 

1 + 0.1;        // 1.1
0.1 + 0.2;      // 0.30000000000000004

parseInt(1.1, 10);   // 1
Math.floor(1.1);     // 1

String

  • 불변값 (Immutable)
  • '' 와 "" 모두 사용 가능
var hello = 'Hello';
var name = "Steve";
var greet = hello + ', ' + name + '!';

var sen1 = 'My name is "Steve"';
var sen2 = "My name is 'Steve'";

greet;              // 'Hello, Steve!'
hello == 'Hello';   // true
name === 'Steve';    // true

== vs ===

123     ==      "123"           // true
0	==	"0"		// true
0	==	""		// true
""	==	"0"		// false

0       ==      false           // true
1       ==      true            // true
2       ==      true            // false

false	==	"false"		// false
false	==	"0"		// true
false   ==      ""              // true
false	==	undefined	// false
false	==	null		// false
null	==	undefined	// true

== vs ===

123     ===     "123"           // false
0	===	"0"		// false
0	===	""		// false
""	===	"0"		// false

0       ===     false           // false
1       ===     true            // false
2       ===     true            // false

false	===	"false"		// false
false	===	"0"		// false
false   ===     ""              // false
false	===	undefined	// false
false	===	null		// false
null	===	undefined	// false

Wrappers

var num1 = 1;
var num2 = new Number(1);  

typeof num1; // 'number'
typeof num2; // 'object'

num1 == num2;  // true
num1 === num2; // false

num1.toString();  // '1'
num2.toString();  // '1'
(1).toString();   // '1'

// new String('A'); 
// new Boolean(true);
  • 되도록 사용하지 말 것
  • Primitive 값으로도 메소드 사용 가능

Object

  • 속성(Property)들의 집합(Collection)
// 빈 객체 생성
var obj1 = new Object(); // (권장 X)
var obj2 = {};           // (권장 O)

// 객체 리터럴
var person = {
  name: 'John',
  age: 30,
  married: true
};

// 속성값 사용
console.log(person.name);      // 'John'
console.log(person['age']);    // 30
var propName = 'married';
console.log(person[propName]); // true

Object

  • 동적으로 속성값 할당/해제
var person = {
  name: 'John'
};

// 속성값 할당
console.log(person.age); // undefined
person.age = 30;
console.log(person.age); // 30

// 속성값 삭제
delete person.name;
console.log(person.name); // undefined

Array

  • 순서와 length를 갖는 Object
// 빈 배열 생성
var arr1 = new Array();  // 권장 (X)
var arr2 = [];           // 권장 (O)

// 배열 리터럴
var arr3 = [1, 2, 3, 4, 5];
var arr4 = [1, true, {a:10}, 'hello'];

// 배열 요소 사용
console.log(arr3[0]);      // 1
console.log(arr4[2].a);    // 10

// 배열의 길이
console.log(arr3.length); // 5
console.log(arr3[5]);     // undefined




Array

var arr = [1, 2, 3, 4, 5];

console.log(arr.length);  // 5;

arr.length = 6;
console.log(arr.length); // 6
console.log(arr[5]);     // undefined

arr[8] = 100;
console.log(arr[8]);      // 100
console.log(arr[7]);      // undefined
console.log(arr.length);  // 9;

arr.length = 4;
console.log(arr.length);  // 4;
console.log(arr[4]);      // undefined

delete arr[3];
console.log(arr.length);  // 4;
console.log(arr[3]);      // undefined

Array

var arr = [1, 2, 3];

// 기존 배열 변경 API
arr.push(100);

console.log(arr);  // [1, 2, 3, 100]

var lastItem = arr.pop();

console.log(lastItem);  // 100
console.log(arr);       // [1, 2, 3]

// 새로운 배열 반환 API
var arr2 = arr.concat([100, 200]);
console.log(arr);  // [1, 2, 3]
console.log(arr2); // [1, 2, 3, 100, 200]

var arr3 = arr.slice(0, 2);
console.log(arr);  // [1, 2, 3]
console.log(arr3); // [1, 2]

Function

함수 선언문

function add(a, b) {
  return a + b;
}

var result = add(1, 2);
conosle.log(result);      // 3

console.log(add.length);  // 2
console.log(add.name);    // 'add'
console.log(typeof add);  // 'function'

함수 표현식

var add = function(a, b) {
  return a + b;
};

var obj = {
  hello: function(name) {
    return 'Hello, ' + name;
  }
};

var arr = [
  function() {return '1';},
  function() {return '2';} 
];

console.log(add(1, 2));         // 3
console.log(obj.hello('John')); // 'Hello, John'
console.log(arr[0]());          // '1'

기명 함수 표현식

var add = function(a, b) {
  return a + b;
};

var add2 = function add2(a, b) {
  return a + b;
}

console.log(add.name);    // ''
console.log(add2.name);   // 'add2'

First-class function

function add10(value) {
  return value + 10;
}

// 변수로 함수 할당
var add = add10;
console.log(add === add10)      // true
console.log(add(10));           // 20

// 함수의 파라미터로 함수 전달
function addTwice(addFn, value) {
  return addFn(addFn(value));
}
console.log(addTwice(add10, 10));  // 30

First-class function

var arr = [1, 2, 3, 4, 5, 6];

arr.forEach(function(value, index) {
  console.log(value);
});

var evenArr = arr.filter(function(value) {
  return value % 2 === 0;
});
console.log(evenArr);  // [2, 4, 6]

window.setInterval(function() {
  console.log('Tick!');
}, 1000);

CallBack Function

Scope

Block Scope (X)

if (true) {
  var test = 100;
}

console.log(test);   // 100


var test = 100

if (true) {
  var test = 200;
}

console.log(test);   // 200


Function Scope

var num = 100;

function test() {
  var num = 200;
}

test();
console.log(num);    // 100

function test() {
  var num = 100;
}

test();
console.log(num);    // Reference Error!


Scope Chain

var num = 1;

function test1() {
  var num1 = 100;

  function test2() {
     var num2 = 200;

     function test3() {
       console.log(num, num1, num2);
     }
     test3();
  }
  test2();
}

test1();  // 1, 100, 200

Lexical Scope

var num = 1;

function test1() {
  var num1 = 100;
  test2();
}

function test2() {
  var num2 = 200;
  test3();
}

function test3() {
   console.log(num, num1, num2);
}

test1();  // RererenceError!

Closure

function getAddFn(operand) {
  return function(value) {
    return value + operand;
  }
}

var add10 = getAddFn(10);
var add20 = getAddFn(20);

console.log(add10(10));         // 20
console.log(add20(10));         // 30
console.log(getAddFn(30)(10));  // 40

함수가 정의되는 시점의 참조값을 메모리에 유지

전역 변수

var num1 = 100;       // 전역 변수

function test() {
  var num2 = 200;  // 지역 변수
  num3 = 300;      // 전역 변수?
}

test();
console.log(num3);        // 300
console.log(window.num1); // 100
console.log(window.num3); // 300

항상 var 키워드를 사용할 것!

즉시 실행 함수

(function() {
  var num1 = 100;
  var num2 = 200;

  console.log(num1 + num2);
})();  // 300

console.log(num1); // ReferenceError!
console.log(num2); // ReferenceError!

Immediately-Invoked Function Expression (IIEF)

Hoisting

var num = 10;

(function() {
  num = 20;

  var num;
})();

console.log(num);   // ??

Hoisting

function() {
  num1 = 10;

  var num2 = 20;
  var num1;
}

모든 변수나 함수 선언은 Parsing 단계에서 상단으로 끌어올려짐

function() {
  var num1, num2;

  num1 = 10;
  num2 = 20;
}

Hoisting

console.log(hello());
console.log(hi()); 

function hello() {
  return 'hello!';
}

var hi = function() {
  return 'hi';
}
function hello() {
  return 'hello!';
}
var hi;

console.log(hello());
console.log(hi()); 

hi = function() {
  return 'hi';
}

함수 선언문은 함수의 내용까지 Hoisting 됨

실습 1

Mission 1

var funcs = [];

for (var i = 0; i < 3; i++) {
  funcs[i] = function() {
    console.log('idx: ' + i);
  };
}

funcs[0]();   // ?
funcs[1]();   // ?
funcs[2]();   // ?

Mission 2-1

function getCounter(step) {
  // 이 함수를 작성하세요.
}

var counter = getCounter(5);

console.log(counter());  // 5
console.log(counter());  // 10
console.log(counter());  // 15



Mission 2-2

function getCounter(step) {
  // 이 함수를 작성하세요.
}

var counter = getCounter(5);

console.log(counter.value()); // 0

counter.increment();
counter.increment();
console.log(counter.value()); // 10

counter.decrement();
console.log(counter.value()); // 5

Mission 3

function tickLog(count) {
  // 이 함수를 작성하세요.
}

tickLog(5);
// 1
// 2
// 3
// 4
// 5

  • 1초에 한번씩 주어진 횟수만큼 로그를 남기는 함수
  • setInterval, clearInterval 사용

this

this

function test() {
  return this;
}

console.log(this);     // Window
console.log(test());   // Window

this

var person = {
  firstName: 'John',
  lastName: 'Lennon',
  getName: function() {
    return this.firstName + ' ' + this.lastName;
  }
}

console.log(person.getName());  // 'John Lennon'

this

var person = {
  firstName: 'John',
  lastName: 'Lennon',
  getName: function() {
    return this.firstName + ' ' + this.lastName;
  }
}

var getName = person.getName;
console.log(getName());  // undefined undefined

this

var person = {
  firstName: 'John',
  lastName: 'Lennon',
}

function getName() {
  return this.firstName + ' ' + this.lastName;
}

person.getName = getName;
console.log(person.getName());  // 'John Lennon'

this

var person = {
  firstName: 'John',
  lastName: 'Lennon',
  getName: function() {
    return this.firstName + ' ' + this.lastName;
  }
};

var person2 = {
  firstName: 'George',
  lastName: 'Harrison'
};

person2.getName = person.getName;
console.log(person2.getName());  // ???

apply / call

function getName(lastName) {
  return this.firstName + ' ' + lastName;
}

getName('Lennon');     // 'undefined Lennon'

var john = {
  firstName: 'John'
};

getName.call(john, 'Lennon');    // 'John Lennon'
getName.apply(john, ['Lennon']); // 'John Lennon'

apply / call

var person = {
  firstName: 'John',
  lastName: 'Lennon',
  getName: function() {
    return this.firstName + ' ' + this.lastName;
  }
};

var person2 = {
  firstName: 'George',
  lastName: 'Harrison'
};

person.getName.apply(person2);   // ??
person.getName.call(person2);    // ??

bind

function getName(lastName) {
  return this.firstName + ' ' + lastName;
}

var john = {
  firstName: 'John'
};

var getNameJohn = getName.bind(john);
console.log(getNameJohn('Lennon'));   // 'John Lennon'

var getNameJohnLennon = getName.bind(john, 'Lennon');
console.log(getNameJohnLennon());     // 'John Lennon'

bind

function getName(lastName) {
  return this.firstName + ' ' + lastName;
}

var john = {
  firstName: 'John'
};

var george = {
  firstName: 'George'
};

var getNameJohn = getName.bind(john);
console.log(getNameJohn.call(george, 'Harrison'));  // ??

var getNameGeorge = getNameJohn.bind(george);
console.log(getNameGeorge('Harrison'));             // ??

실습 2

Mission 4

function max(arr) {
  // 구현
}

console.log(max([1, 4, 2, 5]));   // 5

Math.max 함수를 사용해 배열의 최대값 구하기

Mission 5-1

var counter = {
  // 여기를 채워주세요.
}

counter.increment();
counter.increment();

console.log(counter.value);  // 2

counter.decrement();

console.log(counter.value);  // 1

Mission 5-2

counter.start = function() {
  // setInterval 사용
}
  • 1초에 1씩 증가하며 로그를 남기는 함수 추가
  • increment() 함수를 활용할 것

HTML

기본 구조

<!DOCTYPE html>
<html>
  <head></head>
  <body></body>
</html>

<head>

<head>
  <title>페이지 제목</title>
  <meta charset="utf-8" />
  <meta name="Author" content="OpenTutorials" />
  <meta name="viewport" content="width=1280" />
  <link href="toast.css" rel="stylesheet" type="text/css" />
  <script src="toast.js"></script>
</head>
  • 필수 요소
  • 문서에 필요한 정보
  • title, meta, link, script 등

ID, Class, Attribute

<div id="container" class="box">
  <p><a href="http://www.nhnent.com">NHNENT</a></p>
</div>
  • 요소의 특성을 정의
  • ID는 문서에 단 하나만 존재 (Unique)
  • Class는 유사한 특성을 같는 요소에 사용

CSS

구조

h1 {color: blue; font-size: 12px}

Selector

Property

Value

HTML에 적용

<head>
  <style>
    h1 {color: #ff0; font-size:12px;}
  </style>
</head>
<head>
  <link rel="stylesheet" type="text/css" href="theme.css">
</head>

1. 외부 CSS 파일 Link (권장)

2. <style> 태그 사용

HTML에 적용

<div style="width: 300px">
  <p style="height: 200px"></p>
</div>

3. Inline Style (권장하지 않음)

Selector

  • Type - Tag Name
  • ID - #
  • Class - .
  • Universal - *
  • Attribute - [ ]
  • Psudo-class - :

Combinator

  • Adjacent sibling - A + B
  • General sibling - A ~ B
  • Child  - A > B
  • Descendant - A B

Selector

#container > .item-list > span 

#container span

span ~ *

.round-box .border-line 

div.border-line

.round-box.content-box

.list-items:first-child

input:checked 

Selector

  • document.querySelector(selector)
  • document.querySelectorAll(selector)
  • $(selector)

실습 3

TODO List 만들기

  • HTML 로 TODO List 만들기
  • CSS를 활용해 스타일 추가

Javascript Basic

By DongWoo Kim

Javascript Basic

  • 391