JavaScript는 웹페이지를 동적으로, 프로그래밍적으로 제어하기 위해서 고안된 언어다. 그렇기 때문에 오늘날 가장 중요한 플랫폼이라고 할 수 있는 웹브라우저에서 유일하게 사용할 수 있는 프로그래밍 언어이다. 최근에는 HTML5의 적용이 가속화되면서 지금까지 모바일 환경에서 네이티브 앱(안드로이드, IOS)으로 구현해왔던 기능이 웹에서도 대부분 구현할 수 있게 되고 있다. 웹이 크로스플랫폼이라는 점, 검색 가능하다는 점, 네이티브 디바이스를 제어할 수 있는 하드브리드 시스템이 존재한다는 점에서 웹의 중요함은 더욱 확대될 전망이다. 자연스럽게 웹에서 구동되는 유일한 언어인 JavaScript의 중요함도 점점 커질 것으로 예상된다.
Math.pow(3,2); // 9, 3의 2승
Math.round(10.6); // 11, 10.6을 반올림
Math.ceil(10.2); // 11, 10.2를 올림
Math.floor(10.6); // 10, 10.6을 내림
Math.sqrt(9); // 3, 3의 제곱근
Math.random(); // 0부터 1.0 사이의 랜덤한 숫자
문자열과 문자열을 + 기호로 연결할 수 있다.
alert("coding"+" everybody"); // 결과: coding everybody
alert("coding everybody".length) //결과: 16
변수는 아래와 같이 선언한다.
var a = 1;
var first = "coding";
var은 생략할 수 있지만 이는 유효범위에 영향을 미치기 때문에, var의 의미를 이해하기 전까지는 var을 사용하는 것을 권장한다.
a = 1
변수 a에 숫자 1을 대입한다는 의미로, 비교 연산자는 아니다.
alert(1==2) //false
alert(1==1) //true
alert("one"=="two") //false
alert("one"=="one") //true
좌항과 우항의 값을 비교하여, 일치하면 true 일치하지 않으면 false를 반환한다.
alert(1=='1'); //true
alert(1==='1'); //false
== 연산자는 자료형이 달라도 그 값만 다르면 true를 반환하는데, === 연산자는 자료형까지 같아야만 true를 반환한다. 일반적으로 == 대신 ===를 사용하기를 권장한다.
// ==과 ===의 차이를 보여주는 몇 가지 예시들
alert(null == undefined); //true
alert(null === undefined); //false
alert(true == 1); //true
alert(true === 1); //false
alert(true == '1'); //true
alert(true === '1'); //false
alert(0 === -0); //true
alert(NaN === NaN); //false
var numbering = function () {
i = 0;
while(i < 10){
document.write(i);
i += 1;
}
}
numbering();
// 배열의 생성
var member = ['egoing', 'k8805', 'sorialgi']
// 배열에 담긴 데이터를 꺼내오는 법
alert(member[0]); //결과: egoing
alert(member[1]); //결과: k8805
alert(member[2]); //결과: sorialgi
배열에 담긴 값을 가져올 때 대괄호([ ]) 안에 넣는 숫자를 인덱스라고 한다. 0부터 시작하기 때문에 첫 번째 원소를 가져오려면 대괄호 안에 0을 넣어주어야 한다.
var arr = [1, 2, 3, 4, 5];
alert(arr.length); // 결과: 5
배열 이름 뒤에 .length를 붙이면 배열의 크기를 알아낼 수 있다.
// 배열의 끝에 원소 추가
var example1 = ['a', 'b', 'c', 'd', 'e'];
example1.push('f'); // 배열의 끝에 새로운 원소를 추가한다.
alert(example1); // 결과: a, b, c, d, e, f
// 배열에 복수의 원소를 추가
var example2 = ['a', 'b', 'c', 'd', 'e'];
example2.concat(['f', 'g']); // 배열의 끝에 새로운 원소 2개를 추가한다.
alert(example2); // 결과: a, b, c, d, e, f, g
// 배열의 시작점에 원소를 추가
var example3 = ['a', 'b', 'c', 'd', 'e'];
example3.unshift('z'); // 배열의 시작점에 새로운 원소를 추가하고 기존 값들의 인덱스를 1씩 증가시킨다.
alert(example3); // 결과: z, a, b, c, d, e
// 배열의 중간에 원소를 추가
var example4 = ['a', 'b', 'c', 'd', 'e'];
example4.splice(2, 0, 'B'); // 인덱스가 2인 원소를 포함해 0개의 원소를 삭제하고 그 앞에 B를 삽입한다.
alert(example4); // 결과: a, b, c, B, d, e
splice를 이용하면 복수의 원소를 한 번에 추가할 수도 있다.
// 배열의 첫 번째 원소를 제거
var example5 = ['a', 'b', 'c', 'd', 'e'];
example5.shift();
alert(example5); // 결과: b, c, d, e
// 배열의 마지막 원소를 제거
var example6 = ['a', 'b', 'c', 'd', 'e'];
example6.pop();
alert(example6); // 결과: a, b, c, d
// 배열 정렬하기
var li = ['c', 'e', 'a', 'b', 'd'];
li.sort();
alert(li); // 결과: a, b, c, d, e
// 배열 역순으로 정렬하기
var li = ['c', 'e', 'a', 'b', 'd'];
li.reverse();
alert(li); // 결과: e, d, c, b, a
배열에서는 인덱스라는 숫자가 자동으로 생성되어서, 이를 아이템에 대한 식별자로 사용했다. 만약 인덱스로 문자를 사용하고 싶다면 객체를 사용해야 한다. (솔리디티의 mapping과 비슷한 개념인듯)
// 객체의 생성
var grades = {'egoing': 10, 'k8805': 6, 'sorialgi': 80};
// 객체를 생성하는 또 다른 방법
var grades = {};
grades['egoing'] = 10;
grades['k8805'] = 6;
grades['sorialgi'] = 80;
// 객체를 생성하는 또 또 다른 방법
var grades = new Object();
grades['egoing'] = 10;
grades['k8805'] = 6;
grades['sorialgi'] = 80;
위에서 egoing은 key가 되고 10은 value가 된다. 객체에 데이터를 저장했으니 이를 꺼내오는 방법을 알아보자.
var grades = {'egoing': 10, 'k8805': 6, 'sorialgi': 80};
alert(grades['sorialgi']); // 결과: 80
alert(grades.sorialgi); // 결과: 80
객체에 대하여 반복 작업을 하는 방법을 알아보자.
var grades = {'egoing': 10, 'k8805': 6, 'sorialgi': 80};
for(key in grades) {
document.write("key : "+key+" value : "+grades[key]+"<br />");
}
위 코드의 결과는 아래와 같다.
key : egoing value : 10
key : k8805 value : 6
key : sorialgi value : 80
for 문은 in 뒤에 따라오는 배열(or 객체)의 key 값을 in 앞의 변수에 담아서 반복문을 실행한다. 반복문이 실행될 때 변수 key의 값으로 egoing, k8805, sorialgi가 순차적으로 할당되기 때문에 grades[key]를 통해서 객체의 값을 알아낼 수 있다.
객체 안에 또 객체가 담길 수도, 함수가 담길 수도 있다.
var grades = {
'list': {'egoing': 10, 'k8805': 6, 'sorialgi': 80},
'show' : function(){
for(var name in this.list){
document.write(name+':'+this.list[name]+"<br />");
}
}
};
grades.show();

위 코드의 구조를 그림으로 나타내보았다. grades라는 객체에 list와 show라는 key가 저장되어 있고, list의 value로 새로운 객체가 들어있다. show의 value로는 function이라는 함수가 저장되어있다.
function welcome(){
return 'Hello world';
}
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8"/>
<script src="greeting.js"></script>
</head>
<body>
<script>
alert(welcome());
</script>
</body>
</html>
main.html 파일을 보면 welcome()이라는 함수를 정의하지 않았는데도 사용하고 있다. 그 이유는 바로 welcome이라는 함수가 정의된 파일을 모듈화했기 때문이다. greeting.js 라는 파일에서 welcome 함수를 정의하고, main.html 파일에서
<script src="greeting.js"></script>
이 코드를 사용해서 main.html 파일에서도 welcome 함수를 사용할 수 있게 되는 것이다. (타 언어의 상속과 비슷한 개념인 것 같다.)
난이도가 있는 내용인 것 같아 일단 스킵하고 필요할 때 돌아와서 공부하겠음
유효 범위는 변수의 수명을 의미한다.
함수 밖에서 변수를 선언하면 그 변수는 전역변수가 된다. 전역변수는 에플리케이션 전역에서 접근이 가능한 변수다. 다시 말해서 어떤 함수 안에서도 그 변수에 접근 할 수 있다. 반면 함수 안에서 선언한 변수는 기본적으로 지역변수가 된다. 지역변수는 해당 함수 내에서만 접근 가능한 변수이다.
var vscope = 'global';
function fscope(){
var vscope = 'local';
alert('함수안 '+vscope);
}
fscope();
alert('함수밖 '+vscope);
결과는 함수안 local, 함수밖 global이다. 똑같은 이름의 vscope가 2번 선언되었는데, 전역변수로써 vscope의 값은 global, 지역변수로써 vscope의 값은 local이다. fscope 함수 내에서 vscope에 접근했을 때 local 값이 반환된 것을 통해 지역변수가 전역변수보다 우선된다는 것을 알 수 있다. 반면, 아래 예제를 보자.
var vscope = 'global';
function fscope(){
vscope = 'local';
alert('함수안'+vscope);
}
fscope();
alert('함수밖'+vscope);
결과는 함수안local, 함수밖local이다. 이번엔 왜 함수 밖에서도 vscope의 값이 local이 되었을까? fscope 함수 내에서 변수를 선언할 때 var을 사용하지 않았기 때문이다. var을 사용하지 않은 지역변수는 전역변수가 된다. 따라서 위 에제에 3행에서 전역변수 vscope의 값을 global에서 local로 바꾼 것이 된다.
전역변수는 사용하지 않는 것이 좋다. 여러가지 이유로 그 값이 변경될 수 있기 때문이다. 함수 안에서 전역변수를 사용하고 있는데, 누군가에 의해서 전역변수의 값이 달라졌다면 어떻게 될까? 함수의 동작도 달라지게 된다. 이것은 버그의 원인이 된다. 또한 함수를 다른 에플리케이션에 이식하는데도 어려움을 초래한다. 함수의 핵심은 로직의 재활용이라는 점을 상기하자. 변수를 선언할 때는 꼭 var을 붙이는 것을 습관화해야 한다. 전역변수를 사용해야 하는 경우라면 그것을 사용하는 이유를 명확히 알고 있을 때 사용하도록 하자.
javascript에서는 함수에 대한 유효범위만을 제공한다. 많은 언어들이 블록에 대한 유효범위를 제공하는 것과 다른 점이다.
for(var i = 0; i < 1; i++){
var name = 'coding everybody';
}
alert(name);
자바스크립트에서 위 코드의 결과는 coding everybody이다.
for(int i = 0; i < 10; i++){
String name = "egoing";
}
System.out.println(name);
반면 자바에서 위 코드는 허용되지 않는다. name은 지역변수로 for문 안에서 선언된 것인데 이를 for문 밖에서 호출하고 있기 때문이다.
JavaScript에서는 함수도 객체다. 다시 말해서 일종의 값이다. 거의 모든 언어가 함수를 가지고 있다. JavaScript의 함수가 다른 언어의 함수와 다른 점은 함수가 값이 될 수 있다는 점이다.
function a(){}
위 코드에서 함수 a는 변수 a에 담겨진 값이다. 또한 함수는 객체의 값으로 포함될 수 있다. 그렇게 객체의 값으로 담겨진 함수를 메소드라고 부른다.
a = {
b:function(){
}
};
위 코드에서 a라는 객체에 b라는 key가 있고, 그 key에 대한 value로 function()이라는 함수, 즉 메소드가 담겨있다.
또, 함수는 값이기 때문에 다른 함수의 인자로 전달될 수도 있다.
function cal(func, num){
return func(num)
}
function increase(num){
return num+1
}
function decrease(num){
return num-1
}
alert(cal(increase, 1)); // 결과: 2
alert(cal(decrease, 1)); // 결과: 0
함수가 함수의 리턴 값으로 사용될 수도 있다.
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)); // 결과: 3
alert(cal('minus')(2,1)); // 결과: 1
함수가 배열의 값으로 사용될 수도 있다.
var process = [
function(input){ return input + 10;},
function(input){ return input * input;},
function(input){ return input / 2;}
];
var input = 1;
for(var i = 0; i < process.length; i++){
input = process[i](input);
}
alert(input); // 결과: 60.5