IT 인터넷

JavaScript 왕초보 자바스크립트 기초 문법 정리

탁이 2019. 10. 26. 09:34

자바스크립트 기초 문법을 간단히 파악할 수 있는 외국사이트를 번역해서 올립니다. 본인도 배우는 중이라 답변이 어려울 수도 있으니 양해 바랍니다.

자바스크립트 실행 (브라우저 편)

자바스크립트로 작성된 스크립트를 실행하기 위해서는 브라우저를 사용하는 것이 가장 빠릅니다. 한 줄로 끝나는 스크립트를 실행하는 경우라면 브라우저의 주소창에 다음과 같이 써 넣습니다. 

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을 확장 할 경우 효과 범위가 크기 때문에주의해야합니다.