자바스크립트 기초 문법을 간단히 파악할 수 있는 외국사이트를 번역해서 올립니다. 본인도 배우는 중이라 답변이 어려울 수도 있으니 양해 바랍니다.
자바스크립트 실행 (브라우저 편)
자바스크립트로 작성된 스크립트를 실행하기 위해서는 브라우저를 사용하는 것이 가장 빠릅니다. 한 줄로 끝나는 스크립트를 실행하는 경우라면 브라우저의 주소창에 다음과 같이 써 넣습니다.
javascript : 실행하고자하는 프로그램
예를 들어, 메시지를 표시 할 경우 다음과 같이 합니다.
javascript : alert ( "aaa" );
여러 줄의 자바스크립트를 실행시키기 위해서는 자바스크립트의 소스 코드 뿐만 아니라 다음과 같은 HTML을 쓰고 그것을 브라우저에 로드해야합니다.
< html >
< head >
< title > JavaScript 테스트 </ title >
<! - HTML에서 직접 소스 코드를 작성하는 경우 ->
< script type = "text / javascript" > <! -
// 여기에 코드를 작성
// ->
</ script >
<! - 외부 소스 코드 파일을로드하는 경우 ->
< script type = "text / javascript" src = "javascript 파일 이름" > </ script >
</ head >
< body >
<! - script 요소는 body에두고도 OK ->
< script type = "text / javascript" > </ script > </ body > </ html >
브라우저 이외 JavaScript 실행
브라우저에서 JavaScript 와 비교하면 마이너이지만, 다른 언어처럼 쉘에서 JavaScript 를 실행할 수있는 구현도 있습니다. 여기에서는 자세히 다루지 않겠습니다.
기초 문법
print 문
자바스크립트의 표준 라이브러리에는 입출력 관련 함수가 전혀 정의되어 있지 않습니다! 문자열을 출력하려면 브라우저에서 구현되는 alert 함수를 이용하는 것이 많습니다.
alert ( "Hello, world" );
또한 최근에는 많은 브라우저에서 console.log 를 지원하고 있기 때문에, 콘솔 윈도우에 메시지를 발송할 수 있습니다 (Firefox의 경우 Firebug가 설치되어 있어야 합니다). console.log 를 사용하면 문자열뿐만 아니라 다양한 객체를 출력 할 수 있습니다.
console.log ( "Hello, world" );
console.log ( [ 1, 2, 3 ] );
주석 (코멘트)
코멘트는 C 계열의 언어와 동일합니다.
// 한줄 주석
/ *
여러
줄의
주석
* /
문법 검사
차세대 버전의 JavaScript (ECMAScript 5)에서는 Strict 모드는 보다 엄격한 문법 검사를 수행하는 모드의 도입이 예정되어 있습니다. 향후는 Perl 처럼 Strict 모드에서 스크립트를 쓰는 것이 상식이 될 가능성이 높은 것 같아서, 지금부터 JavaScript 를 기억한다면 정확한 작성을 익혀 두는 것이 좋습니다. Strict 모드로하기 위해서는, 스크립트 시작 부분에 다음 문자열을 씁니다. 이 코드 자체는 단순한 문자열이므로 Strict 모드를 지원하지 않는 브라우저에는 아무런 영향을주지 않습니다.
"use strict" ;
* 브라우저 외에서 실행할 때는 지원 여부 확인 필요. 처리계에서 안쓰는 편이 좋음
문법
문장의 끝에는 세미콜론 (;)을 넣습니다. 지정하지 않으면 자동으로 보충되지만 가끔 의도하지 않은 동작을 일으킬 수 있기 때문에, 익숙해지기 전에는 붙이도록하는 것이 무난합니다.
변수 선언
var로 선언합니다. 변수 형식은 없습니다.
var hoge = 1;
hoge = "a" ; // 숫자도 문자도 할당 할 수 있다
선언하지 않은 변수에 값을 할당 할 수 있지만 이 경우 전역 변수가 만들어 거기에 대입됩니다 (엄밀하게는 조금 다르지만). 정의되지 않은 변수에 할당 작업은 Strict 모드에서 오류가되므로, 변수를 사용할 때는 선언을 습관화해 두는 것이 좋습니다.
a = 1; // 정의되지 않은 변수에 대입는 에러가되지 않는다
수
자바스트립트의 수치는 모두가 실수입니다. 정수형 개념은 없습니다.
var d = 123456; // 10 진수 정수
var h = 0xffff; // 16 진수
var o = 0123; // 8 진수 (Strict 모드에서 구문 오류가 발생합니다)
var f = 12.345; // 실수
연산
자바스트립트는 실수 밖에 없기 때문에, 연산의 결과도 실수입니다. 그러나 비트 연산의 경우 소수점 이하를 버리고 정수로 변환하고 나서 이루어집니다.
var a = 1 + 2; // => 3
a = 3 - 2; // => 1
a = 1 * 5; // => 5
a = 3 / 2; // => 1.5 (정수끼리의 나눗셈 하지만 결과는 실수)
a = 3 % 2; // => 1 (여)
a = 255.1 & 2.1; // == 255 & 2 => 2 (비트 연산은 정수로 변환 (소수점 이하 버림)하고 열리는)
a = 12.3 >> 1; // => "6"(ibid.)
대입 연산자와 증가 · 감소
C 계열 언어처럼 사용할 수 있습니다.
var a = 0;
a + = 3; // => 3
a - = 2; // => 1
a * = 3; // => 3
a / = 3; // => 1
a = 0;
var b = a ++; // => a == 1, b == 0
var c = ++ a; // => a == 2, c == 2
var d = a--; // => a == 1, d == 2
var e = --a; // => a == 0, e == 0
문자열
문자열은 작은 따옴표 ( ') 또는 큰 따옴표 ( ")로 묶습니다. 양자는 완전히 동일합니다. 양쪽 모두 \ t (탭), \ n (개행) 등의 특수 문자 를 사용할 수 수 있습니다. 다른 스크립트 기반 언어의 변수 확장 등의 편리한 기능은 없습니다.
var a = "abc \ t def" ; // "abc [tab] def"([tab] 탭 문자)
var b = 'abc \ t def' ; // "abc [tab] def"
문자열 조작
결합
var join1 = 'aaa' + 'bbb' ;
var join2 = [ 'aaa' , 'bbb' , 'ccc' ] .join ( '' ); // => 'aaa, bbb, ccc'
분할
var record = 'aaa, bbb, ccc' .split ( /, / ); // => 'aaa', 'bbb', 'ccc']
길이
var length = 'abcdef' .length; // => 6
잘르기 (substr 많은 환경에서 지원되어 있지만 비표준적인 방법이므로 일단주의)
var substr = 'abcd' .substr (1, 2); // => bc
var substring = 'abcd' .substring (1, 2); // => b
검색
// 찾으면 그 위치 없으면 -1을 반환
var result1 = 'abcd' .indexOf ( 'cd' ); // => 2
var result2 = 'abcd' .indexOf ( 'ef' ) ; // => -1
배열
배열의 생성 방법 여러가지.
var ary1 = [ 1, 2, 3 ] ; // => 1, 2, 3]
var ary2 = new Array (3); // => undefined, undefined, undefined]
var ary3 = new Array (3, 4, 5); // => 3, 4, 5]
배열의 참조와 대입
var ary = [ 1, 2, 3 ] ;
ary [ 2 ] ; // => 3 (배열의 인덱스는 0 원)
ary [ 0 ] = 3; // => ary == [3, 2, 3]
요소의 개수
ary.length
배열을 사용한 작업
var ary = [ 1, 2, 3 ] ;
// 선두를 꺼내기
var a = ary.shift (); // => a == 1 ary == [2,3]
// 앞에 추가
ary.unshift (5); // => ary == [5, 2, 3]
// 끝을 꺼내기
var b = ary.pop (); // => b == 3, ary == [5, 2
// 끝에 추가
ary.push (9); // => ary == [5, 2, 9]
// 부분의 사본을 얻기
var c = ary.slice (1, 2);
// => c == [2] ary == [5, 2, 9]
// 일부를 대체
var d = ary.splice (1, 2, "a" , "b" , "c" );
// => d == [2, 9, ary == [5 "a", "b", "c"]
연관 배열 (같은 것)
JavaScript 는 연관 배열 이라고하는 것은 아니지만 어떤 객체를 연관 배열 처럼 처리 할 수 있습니다.
// 객체의 정의. JSON은이 표기법을 기반으로하고있다
var a = { a : 123, b : 456 } ;
a [ 'a' ] ; // => 123 (연관 배열 바람 액세스)
ab; // => 456 (속성 바람 액세스)
a [ 'c' ] = 789; // 요소 추가
ad = 123;
다음과 같은 작성도 가능하지만, 보통은하고 있지 않습니다.
"abc" [ 'length' ] ; // => 3 (속성 가져 오기)
"a, b, c" [ 'split' ] ( /, / ); // => [ "a", "b", "c"(메서드 호출)
연관 배열 바람의 액세스와 속성 바람의 액세스는 표기 만 다른 의미상의 차이는 없습니다.
제어문
if 문
if (조건) {
hoge ();
fuga ();
}
// if중인 문장이 하나의 경우 괄호 ( "{", "}")를 선택적
if (조건)
hoge ();
if-else 문
if (조건) {
} else {
}
else 다음에 또 조건 분기를 거듭할 때는 다음과 같이 쓰기도합니다.
if (조건 1) {
// 조건이 true
} else if (조건 2) {
// 조건이 false에서 조건 2가 true
} else if (조건 3) {
// 조건 1, 2가 false로 조건 3 가 true
} else {
// 조건 1, 2, 3이 false
}
중괄호를 생략하지 않고 쓰면 다음과 같이됩니다.
if (조건 1) {
// 조건이 true
} else {
if (조건 2) {
// 조건이 false에서 조건 2가 true
} else {
if (조건 3) {
// 조건 1, 2가 false로 조건 3가 true
} else {
// 조건 1, 2, 3이 false
}
}
}
while 문
var i = 0;
while (i <5) {
i ++;
}
for 문
for ( var i = 0; i <5; i ++) {
}
for in 문
var obj = { a : 1, b : 2 } ;
for ( var i in obj) {
alert (obj [ i ] ); // => 1, 2
}
for each 문 ( Firefox 전용)
var obj = { a : 1, b : 2 } ;
for each ( var v in obj) {
alert (v); // => 1, 2
}
Array # forEach (최근 브라우저에서만 사용 가능)
[ "a" , "b" , "c" ] .forEach ( function (v, i) {
alert (i + ":" + v); // => "0 : a", "1 : b" "2 : c"
} )
switch 문
구문은 C와 함께입니다. break가 필요합니다.
var a = 0;
switch (a) {
case 0 : alert ( 'zero' ); break ;
case 1 : alert ( 'one' ); break ;
case 2 : // fall through
case 3 : alert ( 'two or three ' ); break ;
default : alert ( 'many! ' ); break ;
}
C와 달리 case 후에는 런타임에 계산되는 값을 포함 할 수 있습니다.
switch (a) {
case a + ' : alert ( 'String ' ); break ;
case a + 0 : alert ( 'Number ' ); break ;
case !! a : alert ( 'Boolean ' ); break ;
default : alert ( 'Something' ); break ;
}
함수
많은 경우, 함수의 선언은 다음과 같이 씁니다.
function sum3a (a, b, c) {
return a + b + c;
}
JavaScript 함수는 퍼스트 클래스의 개체이므로 변수에 할당 할 수 있습니다 (함수식).
var sum3b = function (a, b, c) {
return a + b + c;
} ;
sum3a는 컴파일시에 정의되어 sum3b는 실행시에 정의됩니다. 그 이외의 점에서 양자의 차이는 없습니다. Firefox 의 경우 return 문 만 포함 된 같은 함수는 다음과 같은 단축 표기를 사용할 수 있습니다 (식 폐쇄 기법).
var sum3b = function (a, b, c) a + b + c;
// var sum3b = function (a, b, c) {return a + b + c;}과 동일
파일 입출력
브라우저에서 실행되는 JS의 경우 그런 것은 없습니다. 서버와 통신 할 수 있지만 복잡해서 생략 ( XMLHttpRequest을 검색하세요)
정규표현
JavaScript 에서 사용할 수있는 정규식 플래그 특수 문자는 RegExp - JavaScript | MDN 에 정리되어 있습니다. 정규식 개체는 다음과 같이 만듭니다.
var regex1a = / \ d + / ; // 정규식 리터럴을 사용
var regex1b = new RegExp ( ' \\ d +' ); // 문자열에서 생성 (regex1a와 등가)
var regex2a = / \ s + / g ; // g 옵션을 부여
var regex2b = new RegExp ( ' \\ s +' , 'g' );
// 슬래시를 많이 포함하면 문자열에서 생성하는 것이 읽기 쉬운
var urlRegA = / ^ http : \ / \ / [ ^ \ /] + \ / $ / ;
var urlRegB = new RegExp ( '^ http : // [^ / + / $');
문자열에서 생성하는 경우, \ d 등의 특수 문자 를 \\ d를 써야한다는 점에주의하십시오.
검색
정규식을 사용한 검색 방법은 4 가지가 있습니다.
var regex = / [az] (\ d +) / ;
// 일치 여부 만 검사 방법이 2 가지
// RegExp # test
regex.test ( '! a123!' ); // => true
regex.test ( '! 123!' ); // => false
// String # search
'!! a123!' .search (regex); // => 2
"! 123!" .search (regex); // => -1
// 자세한 경기 정보를 얻는 방법은 두 가지
// RegExp # exec
var m1 = regex.exec ( 'aaa123' );
m1 [ 0 ] ; // => a123 (성냥 한 부분 전체)
m1 [ 1 ] ; // => 123 (1 번째 괄호 ()로 캡처 된 부분)
m1.index; // => 2 (매치 위치)
// String # match
var m2 = 'aaa123' .match (regex);
//이 경우 얻어진 결과는 RegExp # exec 같은 (m2 == m1)
정규 표현식 에 g 플래그를 설정하면 RegExp # exec, String # match 동작이 바뀝니다. 우선 RegExp # exec 대해.
var s = '123' ;
var r = / \ d / ; // g 플래그없이
var rg = / \ d / g ; // g 플래그가
// g 플래그가 없으면 매번 같은 결과
r.exec (s); // => 1
r.exec (s); // => 1
r.exec (s); // => 1
r.exec ( s); // => 1
// g 플래그가 있으면 전회의 매치의 다음 부분에서 검색을 시작하는
rg.exec (s); // => 1
rg.exec (s); // => 2
rg.exec (s); // => 3
rg.exec (s); // => null
문자열에서 일치하는 모든 부분에 대해 뭔가 처리를 실시하고 싶을 때 다음과 같은 쓰기를하거나합니다.
var s = 'string' ;
var m;
while ((m = / [az] / g .exec (s))! == null ) {
alert (m [ 0 ] ); // => 's', ' t ','r ','n ','g '
}
다음 String # match의 경우. g 플래그의 유무에 전혀 다른 행동을 보여주기 때문에주의가 필요합니다.
var r = / \ d (\ d) \ d / ;
var rg = / \ d (\ d) \ d / g ;
// g 플래그가없는 경우 exec와 똑같은
var m1 = '123456' .match (r); // => m1 [0] == '123', m1 [1] == '2', m1.index = = 0
// g 플래그가있는 경우 문자열에서 일치하는 부분 모두를 포함하는 배열을 반환
// 괄호로 캡처 한 부분의 취득은 할 수 없습니다
var m2 = '123456' .match (r); // = > 123, 456]
대체
"123" .replace ( / \ d / , 'a' ); // => 'a23'
"123" .replace ( / \ d / g , 'a' ); // => 'aaa'
제 2 인수에 전달할 문자열의 $ n (n> 0)는 정규식 에서 괄호로 캡처 한 부분을 대체합니다.
// 괄호로 캡처 한 부분을 이용하는
"___a123___" .replace ( / [az] (\ d) (\ d) (\ d) / , '[[$ 1 | $ 2 | $ 3]]' ); // = > '___ [1 | 2 | 3] ___'
제 2 인수에는 함수를 전달할 수 있습니다.
var s = "___a123___" .replace ( / [az] (\ d) (\ d) (\ d) / , function (m0, m1, m2, m3) {
alert (m0); // => 'a123'
alert (m1); // => '1'
alert (m2); // => '2'
return m3;
} );
alert (s); // => ___3___
예외 처리
try {
throw new Error ( "오류!" );
} catch (e) {
alert ( "오류가 발생했습니다! \ n 설명 :" + e.message);
} finally {
alert ( "끝" );
}
throw 던질 수있는 객체에 제한은 없습니다.
try {
throw "aaa" ;
} catch (e) {
alert (e);
}
오류 유형을 판별하려면 다음과 같이합니다.
try {
doHogeHoge ();
} catch (e) {
if (e instanceof EvalError) {
// do something.
} else if (e instanceof RangeError) {
// do something.
}
}
Firefox 이라면 다음과 같이 작성도 할 수 있습니다.
try {
doHogeHoge ();
} catch (e if e instanceof EvalError) {
// do something.
} catch (e if e instanceof RangeError) {
// do something.
} catch (e) {
// other error
}
객체 지향
JavaScript 는 프로토 타입 기반 객체 지향 언어 입니다. 변수에 할당 할 수있는 것은 모든undefined 등의 특수한 값을 제외하고 대부분이객체 입니다.로 처리 할 수 있습니다. (숫자 나 문자열 true, false 등은 기본 값이라고 개체는 아니지만 도트 연산자 로 속성에 액세스 할 수있는 등 개체로 취급 할 수 있습니다. 이것은 객체 인 행동이 필요 하는 경우 기본 값이 자동으로 객체로 변환되기 때문입니다).
개체의 정의
var obj = { a : 123, b : 3 } ;
obj.a; // => 123
메소드
메소드는 속성에 함수를 대입 한 것입니다.
var man = {
hello : function () { alert ( 'hello!' ); } ,
bye : function () { alert ( 'bye' ); }
} ;
man.hello (); // => hello!
클래스 비슷한것
함수를 만들고 그 prototoype 속성을 만져서 클래스와 같은 개체를 만들 수 있습니다.
// 클래스 (같은 것)의 정의
// 생성자되는 함수
var Man = function (name, age) {
// 속성 초기화
this .name = name;
this .age = age;
} ;
// 메소드 속성의 정의
Man.prototype = {
sayName : function () { alert ( "My name is" + this .name + "" ); }
}
// 인스턴스 생성
var bob = new Man ( 'Bob' , 35);
bob.sayName (); // => My name is Bob.
상속
prototype 부모 클래스의 객체를 대입하여 상속이 가능합니다.
var Animal = function () {} ;
Animal.prototype = {
sleep : function () { alert ( 'zzz ...' ); }
} ;
var Human = function () {} ;
Human.prototype = new Animal ();
Human.prototype.workHarder = function () {
alert ( "I 'm tired ..." );
this .sleep ();
} ;
var me = new Human ();
me.workHarder (); // => I 'm tired ... => zzz ...
잡다한 tips
부울
JavaScript 에서는 다음의 값이 false로 처리됩니다.
-
false (Bool 형)
-
0 (실수)
-
""(빈)
-
null 또는 NaN, undefined
이것 이외는 모두 true로 간주됩니다.
==와 ===
== 의한 비교는 자동으로 형 변환을 수행 후 비교되기 때문에 의도하지 않은 결과를 가져올 수 있습니다.
'0' == 0; // => true
'' == 0; // => true
'100' == 100 // => true
이러한 사태를 방지하기 위해 형식 변환을 하지않고, 비교 연산자 ===를 사용하는 것이 좋습니다.
'0' === 0; // => false
'' === 0; // => false
'100' === 100 // => false
변수의 범위
변수의 범위는 선언된 함수 내의 전체입니다. 함수 내의 어느 위치에서 변수 선언해도 함수 전체에서 변수를 참조 할 수 있습니다.
var a = 0;
function () {
alert (a); // => undefined (함수에서 나중에 정의 된 a를 참조하는)
var a = 1; // 여기에서 a에 값이 대입되는
if ( true ) {
var b = 1; // 여기에서 정의한 b는 함수 내 어느 곳에서나 볼 수있는
}
alert (b); // => 1 (if 문에서 선언 한 b를 볼 수)
}
Firefox 라면 다음과 같이하여 범위가 블록에 한정되는 변수를 선언 할 수 있습니다.
if ( true ) {
let b = 1;
}
alert (b); // => 정의되지 않은 오류 (let 선언하는 범위가 if 문안에 한정되는)
this가 가리키는 것
메소드에서 사용되는 this가 가리키는 것은 그 메소드의 호출 방법에 따라 달라집니다. 구체적으로는 obj.hoge ();의 형태로 불려 갔을 경우 this는 obj되고 hoge ();의 형태로 불려 갔을 경우 this는 window (전역 개체)입니다.
var smith = {
name : "Smith" ,
sayName : function () { alert ( this .name); }
} ;
smith.sayName (); // => Smith
var john = { name : "John" } ;
john.sayName = smith.sayName; // 함수를 대입
john.sayName (); // => John
var sayName = john.sayName;
sayName (); // => undefined (this가 window를 가리키는 데 this.name == window.name == undefined)
this가 가리키는 것을 명시하고하고 함수를 호출하려면 Function # call이나 Function # apply를 사용합니다.
// 위의 코드가 더
sayName.call (smith); // => Smith (this가 smith를 가리킨다)
sayName.apply (john); // => John (this가 john을 가리킨다)
Function # call와 Function # apply의 차이는 호출하려는 함수에 전달되는 인수의 지정 방법입니다. apply는 배열로 인수를 전달 해주고 있습니다.
function hoge (a, b, c) {
return a + b + c;
}
// 이들은 동일
hoge (1, 2, 3); // => 6 (this는 window를 가리킨다)
hoge.call ( null 1, 2, 3); // => 6 (this는 window)
hoge.apply ( null , [ 1, 2, 3 ] ); // => 6 (this는 window)
기존 개체의 확장
기존 객체의 prototype을 만지는 것으로 기존 개체를 확장 할 수 있습니다.
[ 1, 2, 3 ] .sum (); // => Error (sum is not a function)
Array .prototype.sum = function () {
var sum = 0;
for ( var i = 0; i < this . length; i ++) {
sum + = this [ i ] ;
}
return sum;
} ;
[ 1, 2, 3 ] .sum (); // => 6
for in 문의 함정기존 개체 확장의 함정 for in 문에는 prototype에 정의 된 속성을 열거해 버리므로주의가 필요합니다.
Object .prototype = { doHoge : function () {}} ;
var obj = { a : 1, b : 2 } ;
for ( var i in obj) {
alert ( "i =" + obj [ i ] ); // => "a = 1", "b = 2", "doHoge = function () {}"
}
이러한 동작을 방지하기 위해서는 hasOwnProperty를 사용하여 그 개체 자체가 가지고있는 속성 여부를 확인합시다.
Object .prototype = { doHoge : function () {}} ;
var obj = { a : 1, b : 2 } ;
for ( var i in obj) {
if (obj.hasOwnProperty (i))
alert ( "i =" + obj [ i ] ); // => "a = 1", "b = 2"
}
기존 개체 특히 모든 객체의 프로토 타입 인 Object.prototype을 확장 할 경우 효과 범위가 크기 때문에주의해야합니다.