<script>
태그 안에 js코드가 들어간다.
<script>
의 속성
type
, 모던 마크업에서 type은 필수 명시가 아니다.languege
, js가 기본 언어이므로 의미가 퇴색 되었다.src=
로 경로를 지정해준다. src
사용시, script
태그 내부 코드는 무시된다.주의
HTML 안에 직접 스크립트를 작성하는건 아주 간단한 스크립트만 한다. 스크립트가 길어지면 별개의 분리된 파일로 만들어 저장하는 것이 좋다.
스크립트를 별도의 파일에 작성하면 브라우저가 스크립트를 다운받아 캐시(cache)에 저장해, 여러페이지가 동일 스크립트 사용시 성능상의 이점이 있다.
문(statement)은 작업을 수행하는 문법구조(structure)와 명령어(command)를 의미
코드의 가독성을 위해 각 문을 서로 다른줄에 작성하거나 세미콜론으로 구분한다.
대부분의 경우, 줄을 바꾸면 암시적 세비콜론이라 해석하고 세미콜론 자동 삽입(automatic semicolon insertion)이라 한다.
주석은 //
이나 /* */
으로 표시. 단축키 ctrl + /
, ctrl + shift + /
프로덕션 서버에 배포전 코드를 압축하는 도구가 주석은 제거해주고 주석은 실행되지 않아 코드에 부정적 영향을 끼치지 않는다.
es5 에서 새로운 기능이 추가 되고 기존 기능 일부가 변경되면서 호환성 문제로, 변경사항이 기본 모드에선 활성화되지 않게 설계되었다. use strict
를 이용해 엄격모드(strict mode)를 활성화해야 변경사항이 적용된다.
'use strict'
가 최상단에 오면 스크립트 전체가 모던한 방식으로, 함수앞에 오면 함수만 모던하게 바뀐다. 따라서, 최상단에 위치하는게 좋다. 엄격모드는 취소 할 수 없다.
브라우저 콘솔에서는 'use strict'
를 쓰고 shift+enter
로 줄바꿈을 해줘야 사용가능.
모던 자바스크립트에서는 class와 module을 사용하면 자동 적용된다.
변수(variable) let
, var
은 데이터를 저장할때 사용하는 저장소.
한번에 여러개를 선언할수 있지만, 가독성을 위해 한줄에 하나의 변수를 작성하는게 좋다.
let
, var
는 거의 동일하게 동작하지만 var
는 오래된 방식이고, 사용하지 않는걸 추천한다.
변수에 값을 넣고, 값을 변환하는 것도 가능하다.
$
, _
만 들어갈 수 있다.let
없이 변수를 선언했을때 use strict
를 사용하면 오류가 발생한다.상수는 const
를 사용한다. 상수는 재할당할 수 없으므로, 변경하려 하면 애러가 발생한다.
기억하기 힘든 값은 대문자 상수로 할당하는, 하드코딩한 값의 별칭을 만들때 사용하는 관습이 있다.
data
나 value
는 아주 명확할때 사용js에서 값은 항상 문자열이나 숫자형 같으 특정한 자료형에 속한다. 여덟가지 기본 자료형이 있다. 변수는 자료형에 관계없이 모든 데이터일수 있다.변수에 저장되는 값의 타입이 언제든 바뀔 수 있는 '동적타입(dynamically typed)'언어이다.
+
, -
, *
, /
, %
, **
Infinity
, -Infinity
, Nan
(연산 오류시)내부 표션 방식 때문에 js에서는 (2^53-1)(9007199254740991) 보다 큰 값 혹은 -(2^53-1) 보다 작은 정수는 '숫자형’을 사용해 나타낼 수 없다.
아주 큰 숫자가 필요할때 BigInt
를 선언해준다. 길이에 상관없이 정수를 나타내고, 값은 정수 리터럴 끝에 n
을 붙여 만든다.
js에선 문자열을 따옴표로 묶는다. 글자형은 없다. 문자형만.
벡틱 :
${...}`로 변수나 표현식을 문자열 중간에 손쉽게 넣을 수 있다.true
와 false
가 있다.
어느 자료형에도 속하지 않는다.
nothing
: 존재하지 않음empty
: 비어있음unknown
: 알수 없음어느 자료형에 속하지 않음. 값이 할당되지 않은 상태를 나타낸다. 변수 선언시, 값이 없으면 undefined
가 자동 할당된다. 명시적으로 할당 가능하나 null
을 사용하는 게 좋다.
객체형을 제외한 다른 형은 한가지만 표현하기에 원시(primitive) 자료형이라 부른다. 객체는 데이터 컬렉션이나 복잡한 개체(entity)를 표현할 수 있다.
심볼형은 객체의 고유한 식별자(unique identifier)를 만드는데 사용한다.
typeof
연산자는 인수의 자료형을 반환한다.
typeof x
typeof(x)
typeof undefined // "undefined"
typeof 0 // "number"
typeof 10n // "bigint"
typeof true // "boolean"
typeof "foo" // "string"
typeof Symbol("id") // "symbol"
typeof Math // "object" (1)
typeof null // "object" (2)
typeof alert // "function" (3)
함수와 연산자에 전달되는 값은 적절한 자료형으로 자동 변환된다.
String(value)
, value+ ''
문자기반 폼(form)을 통해 입력받는 경우, 이런 명시적 형변환이 필수이다. 문자를 변환하면 NaN
이 된다.
Number(value)
, +value
undefined
: NaN
null
: 0
true
, false
: 1
,0
string
: 문자열 처음과 끝 공백 제거, 이후 남은 문자열이 없으면 0
, 아니면 숫자로 변환, 실패하면 NaN
Boolean(value)
0
, null
, undefined
, NaN
: false
'0'
, ' '
: true
우선순위 | 연산자 유형 | 결합성 | 연산자 |
---|---|---|---|
19 | 그룹 | 없음 | ( … ) |
18 | 멤버 접근 | 좌결합성 | … . … |
계산된 멤버 접근 | 좌결합성 | … [ … ] |
|
new (인자 리스트 제공) |
없음 | new … ( … ) |
|
함수 호출 | 좌결합성 | … ( … ) |
|
옵셔널 체이닝 | 좌결합성 | ?. |
|
17 | new (인자 리스트 생략) |
우결합성 | new … |
16 | 후위 증가 | 없음 | … ++ |
후위 감소 | … -- |
||
15 | 논리 NOT | 우결합성 | ! … |
비트 NOT | ~ … |
||
단항 양부호 | + … |
||
단항 부정 | - … |
||
전위 증가 | ++ … |
||
전위 감소 | -- … |
||
typeof |
typeof … |
||
void |
void … |
||
delete (en-US) |
delete … |
||
await |
await … |
||
14 | 거듭제곱 | 우결합성 | … ** … |
13 | 곱하기 | 좌결합성 | … * … |
나누기 | … / … |
||
나머지 | … % … |
||
12 | 더하기 | 좌결합성 | … + … |
빼기 | … - … |
||
11 | 비트 왼쪽 시프트 | 좌결합성 | … << … |
비트 오른쪽 시프트 (en-US) | … >> … |
||
비트 부호 없는 오른쪽 시프트 (en-US) | … >>> … |
||
10 | 미만 (en-US) | 좌결합성 | … < … |
이하 (en-US) | … <= … |
||
초과 (en-US) | … > … |
||
이상 (en-US) | … >= … |
||
in |
… in … |
||
instanceof |
… instanceof … |
||
9 | 동등 | 좌결합성 | … == … |
부등 | … != … |
||
일치 (en-US) | … === … |
||
불일치 (en-US) | … !== … |
||
7 | 비트 AND | 좌결합성 | … & … |
7 | 비트 XOR (en-US) | 좌결합성 | … ^ … |
6 | 비트 OR (en-US) | 좌결합성 | … | … |
5 | 논리 AND | 좌결합성 | … && … |
4 | 논리 OR | 좌결합성 | … || … |
널 병합 연산자 | 좌결합성 | … ?? … |
|
3 | 조건 (삼항) | 우결합성 | … ? … : … |
2 | 할당 (en-US) | 우결합성 | … = … |
… += … |
|||
… -= … |
|||
… **= … |
|||
… *= … |
|||
… /= … |
|||
… %= … |
|||
… <<= … |
|||
… >>= … |
|||
… >>>= … |
|||
… &= … |
|||
… ^= … |
|||
… |= … |
|||
… &&= … |
|||
… ||= … |
|||
… ??= … |
|||
yield |
우결합성 | yield … |
|
yield* |
yield* … |
||
1 | 쉼표 / 시퀀스 | 좌결합성 | … , … |
// 할당연산자 체이닝
let a, b, c;
a = b = c = 2 + 2;
// 복합할당연산자는 산술연산자와 비트연산자 모두 적용 가능
+= -= /= *=
변수에만 사용 가능
++counter
: 전위형counter++
: 후위형& // AND
| // OR
^ // XOR
~ // NOT
<< // LEFT SHIFT
>> // RIGHT SHIFT
>>> // ZERO-FILL RIGHT SHIFT
,
는 보기 힘들고, 코드를 짧게 쓰려는 위도로 가끔 사용된다. 여러표현식을 한줄에 평가가능 하게 한다. 모두 평가 되지만 마지막 표현식의 결과만 반환된다. 우선순위가 매우 낮고, 가독성에 안 좋다.
let a = (1 + 2, 3 + 4);
alert( a ); // 7 (3 + 4의 결과)
불린형으로 반환한다. true
, false
js는 숫자형으로 바꾼다.
alert( '2' > 1 ); // true, 문자열 '2'가 숫자 2로 변환된 후 비교가 진행
alert( '01' == 1 ); // true, 문자열 '01'이 숫자 1로 변환된 후 비교가 진행
// 이런 경우도 있다.
let a = 0;
alert( Boolean(a) ); // false
let b = "0";
alert( Boolean(b) ); // true
alert(a == b); // true!
// === 아닌 경우 undefined, null 비교시 주의
alert( 0 == false ); // true
alert( '' == false ); // true
alert( 0 === false ); // false, 피연산자의 형이 다름
alert( null === undefined ); // false
alert( null == undefined ); // true
alert( null > 0 ); // (1) false
alert( null == 0 ); // (2) false
alert( null >= 0 ); // (3) true
if(...)
문 안에 조건을 평가로, 결과가 true
일 때 코드 블록 실행
0
, ''
, null
, undefined
, NaN
: falsyelse
, else if
로 거짓이거나, 여러 조건 처리 가능
?
괄호가 없어도 되지만, 가독성을 위해 괄호 사용 권유. 다중 사용도 가능. 가독성을 위해 사용할만한 곳에만 적절히 사용
// condition이 truthy라면 value1, 아니면 value2 반환
let result = condition ? value1 : value2;
&&
, ||
, !
, !!
if
를 &&
이나 ||
로 바꾸지 말것, &&
가 ||
보다 우선이다.
// '||'은 첫번째 truthy를 찾는다. 없으면 마지막 값 반환
result = value1 || value2 || value3;
// '||' 단락평가 : 왼쪽에서 시작해 오른쪽으로 가며 평가시작, truthy 만나면 평가 멈춤
// '&&' 은 첫번째 falthy를 찾는다. 없으면 마지막 값 반환
result = value1 && value2 && value3;
스펙에 추가된지 얼마 안되 구식 브라우저는 폴리필이 필요.
nullish 병합 연산자 (nullish coalescing operator) ??
를 사용하면 여러 피연산자 중 '확정되있는' 변수를 찾을수 있다. &&
, ||
과 같이 사용하려면 ()
필요.
// ||는 첫 번째 truthy 값을 반환, ??는 첫 번째 정의된(defined) 값을 반환
let height = 0;
alert(height || 100); // 100
alert(height ?? 100); // 0
let firstName = null;
let lastName = null;
let nickName = "바이올렛";
alert(firstName ?? lastName ?? nickName ?? "익명의 사용자"); // 바이올렛
while (condition) { // condition이 truthy하면 코드 실행
// 코드
// '반복문 본문(body)'이라 불림
}
// 반복(iteration)이 무한반복하지 않게
do { // 먼저 실행한후 condition 확인
// 반복문 본문
} while (condition);
for (begin; condition; step) {
// ... 반복문 본문(body) ...
// condition이 truthy이면 → body를 실행한 후, step을 실행함
// 인라인 변수 선언시, 반복문 안에서만 접근 가능
// 구성요소 생략 가능
}
for (;;) {
// 끊임 없이 본문이 실행됩니다.
// break 사용
}
// if(condition) continue 로 조건 만족시 다음 반복 강제 실행
// continue로 중첩 제거 가능
// '?' 오른쪽엔 break, continue 불가
//반복문 안에서 break <labelName>문을 사용하면 레이블에 해당하는 반복문을 빠져나올 수 있다. 레이블을 마음대로 '점프'하는 것은 아니다.
outer: for (let i = 0; i < 3; i++) {
for (let j = 0; j < 3; j++) {
let input = prompt(`(${i},${j})의 값`, '');
// 사용자가 아무것도 입력하지 않거나 Cancel 버튼을 누르면 두 반복문 모두를 빠져나옵니다.
if (!input) break outer; // (*)
// 입력받은 값을 가지고 무언가를 함
}
}
alert('완료!');
// 일치 비교를 하기 때문에 value 의 자료형이 중요하다.
switch(x) {
case 'value1': // if (x === 'value1')
...
[break] // break이 없으면 다 실행됨
case 'value2': // if (x === 'value2')
...
[break]
default:
...
[break]
}
case 3: // (*) 두 case문을 묶음
case 5:
alert('계산이 틀립니다!');
alert("수학 수업을 다시 들어보는걸 권유 드립니다.");
break;
코드 중에 독자적으로 존재. 함수는 프로그램을 구성하는 구성요소(building block). 함수 사용으로 중복 없이 유사한 동작 코드를 여러번 호출 가능.
function name(parameter1, parameter2, ... parameterN) {
// 함수 본문
}
// 함수 내에서 선언한 지역변수 (local variable)는 함수 안에서만 접근 가능
// 함수 내부에서 함수 외부의 변수인 외부 변수(outer variable) 에 접근, 수정 가능
// 동일 이름이면 내부 변수로
// 매개변수(parameter)
function showMessage(from, text) { // 인자: from, text
alert(from + ': ' + text);
}
// 기본값 : 값이 없어 'undefined'일 때 기본값 할당
// 구식 js에서는 'if', '||', '??'로 기본값 설정
function showMessage(from, text = "no text given") {
alert( from + ": " + text );
}
function showMessage(from, text = anotherFunction()) {
// anotherFunction()은 text값이 없을 때만 호출됨
// anotherFunction()의 반환 값이 text의 값이 됨
}
showMessage(..) // 메시지를 보여줌
getAge(..) // 나이를 나타내는 값을 얻고 그 값을 반환함
calcSum(..) // 합계를 계산하고 그 결과를 반환함
createForm(..) // form을 생성하고 만들어진 form을 반환함
checkPermission(..) // 승인 여부를 확인하고 true나 false를 반환함
함수는 동작 하나만 담당하는게 좋다. 함수가 길어지면 분리해 작성한다. 함수가 간결할때 테스트와 디버깅이 쉽고, 함수 자체로 주석의 역할까지 한다.
let sayHi = function() { // 할당식 표현으로 변수에 바로 할당
alert( "Hello" );
};
function sayHi() { // (1) 함수 생성
alert( "Hello" );
}
let func = sayHi; // (2) 함수 복사
func(); // Hello // (3) 복사한 함수를 실행(정상적으로 실행)
sayHi(); // Hello // 본래 함수도 정상적으로 실행
함수를 함수의 인수로 전달하고, 필요하다면 인수로 전달한 그 함수를 "나중에 호출(call back)" 하는 것
이름이 없는 함수. 외부에서 직접 접근할 수 없다.
js 엔진이 언제 함수를 생성하는지의 차이
let func = (arg1, arg2, ...argN) => {expression}
title
: 사용자에게 보여지는 문자열, default
: 입력 필드의 초깃값(선택)null
이 반환true
, false
를 반환주의사항