본 글은 Udemy(유데미)에서 제공하는 Colt Steele님의 「The Web Developer 부트캠프 2023」 강의를 수강하며 배운 내용을 바탕으로 작성했습니다.
웹 해킹 및 보안에 쓰이는 자바스크립트 코드를 보고 이해할 수 있는 수준에 다다르기 위해 전반적인 내용을 가볍게 훑어보는 기획입니다.
시작하기 전 헛소리
상대: "전공이 뭐예요?"
나: "산업보안학과예요."
상대: "...?"
나: ".. 컴퓨터공학과랑 비슷한데, 해킹 방어를 좀 더 많이 배워요."
상대: "오!! 그럼 해킹할 줄 아세요?!"
나: "아.. 학년이 낮아서 해킹까지는 안 배웠어요..."
사람을 만나서 학과 얘기를 하다 보면 무. 조. 건 위와 같이 대화가 흘러갑니다.
명색이 보안학과인데, 해킹을 할 줄 모른다니! 거의 9년 전부터 보안전문가가 되겠다며 전공까지 보안학과로 와놓고는 정말 구차한 변명이 아닐 수 없습니다.
그래서 '해킹을 본격적으로 공부해 보자!' 마음먹고는 가장 만만한 웹 해킹을 타깃으로 골랐습니다.
하지만 프론트엔드, 특히 자바스크립트를 모르는 상태로 웹 해킹을 하겠다는 말은 더하기를 모르는 채로 곱하기를 하겠다는 말이나 마찬가지였습니다.
예시 코드조차 이해하지 못하는 상태에서는 한계가 명확했습니다.
그래서 '웹해킹을 위한 자바스크립트(Javascript) 훑어보기'라는 이름 그대로,
"코드를 보고 이해할 수 있는 정도는 되자!"라는 목표 아래 포스팅을 시작하게 되었습니다.
개인적인 이야기는 이쯤 하고, 이제 본격적으로 자바스크립트를 살펴봅시다.
자바스크립트는 어떤 언어일까?
자바스크립트의 문법을 살펴보기 이전에, 먼저 자바스크립트가 어떤 언어인지 살펴보도록 하겠습니다.
HTML, CSS, JavaScript
웹 개발에서 HTML, CSS, Javascript 세 가지는 어느 하나라도 빼놓고 말할 수 없는 존재입니다.
HTML(HyperText Markup Language)은 마크업 언어로, 웹 페이지에 내용(데이터)을 표현하는 역할입니다.
CSS(Cascading Style Sheet)는 스타일 시트, 웹 페이지의 내용을 보기 좋게 꾸며주는 역할입니다.
Javascript는 웹 페이지를 동작시키는 역할입니다.
이 중 프로그래밍 언어로 취급되는 것은 Javascript 뿐입니다.
"HTML is not a programming language"라는 유명한 밈도 있죠.
HTML이나 CSS는 데이터를 표현할 뿐입니다. 이와 달리 Javascript에서는 다른 프로그래밍 언어와 마찬가지로 변수, 반복문, 함수 등의 개념이 탑재되어 논리적인 연산을 수행합니다.
Javascript라는 이름의 의미
'자바'스크립트라서 프로그래밍 언어인 JAVA와 연관이 있을 것이라 생각할 수 있지만, 이는 자바스크립트가 개발될 당시 JAVA 언어의 유명세에 편승하기 위한 전략적인 작명이었을 뿐이라고 합니다.
그러면 스크립트는 무슨 의미일까요? 스크립트 언어이기 때문에 스크립트입니다.
스크립트 언어는 이미 존재하는 소프트웨어를 제어하기 위한 언어입니다. 대체로 단순하고, 쉽고, 빠르게 동작하도록 설계됩니다.
한 마디로 정리하면 "웹 애플리케이션을 제어하기 위한 프로그래밍 언어"라고 할 수 있습니다.
원시 타입(Primitive Type)
이제 자바스크립트의 문법을 하나씩 알아가 보도록 합시다.
먼저 원시 타입을 알아보겠습니다.
원시 타입은 '객체도 아니면서 메서드를 가지지 않는 데이터'입니다.
원시 타입이라고 번역하니 별로 와닿지 않는 느낌이죠. 다르게 말하면 "기본" 자료형입니다.
자바스크립트에는 7가지 원시 타입(자료형)이 있습니다.
- number
- bigint
- boolean
- string
- undefined
- null
- symbol
각각의 타입이 어떤 데이터를 나타내는지 하나씩 알아가 보도록 하겠습니다.
변수(variable)
그전에, 우선 '변수'를 알아보겠습니다.
변수는 데이터를 저장하는 공간의 이름입니다.
javascript에서 변수를 선언할 때는 세 가지 키워드를 사용할 수 있습니다.
- let은 일반적인 변수를 선언할 때 사용합니다.
- const는 constant(상수)의 줄임말로, 변경할 수 없는 값을 선언할 때 사용합니다.
- var는 let과 const라는 키워드가 존재하기 이전에 사용했던 변수 선언 키워드입니다.
let age1 = 1;
const age2 = 2;
var age3 = 3;
age1 = 11;
age3 = 33;
age2 = 22; //const 변수는 변경할 수 없음
브라우저의 개발자 도구를 사용해 위 코드를 하나씩 실행해 보면,
const로 선언한 age2는 값을 변경하려 할 때
"Uncaught TypeError: Assignment to constant variable."라는 오류 메시지가 나오는 것을 확인할 수 있습니다.
const 키워드는 왜 존재할까요?
원주율은 3.14로 고정된 값입니다. 이런 값은 수정하면 안 되겠죠.
"수정할 수 없는 값이라는 것은 알겠는데, 그렇다면 개발자가 수정 안 하면 그만이지 않나요?"
코드가 간단하면 "음. 이 값은 수정하면 안 되는 값이지"하고 기억할 수 있겠지만, 100줄, 200줄 넘어가고 변수를 몇 십 개씩 정의하다 보면 하나하나 기억하기 쉽지 않습니다.
다른 개발자와 코드를 공유하여 협업할 때는 더 골치 아픈 일입니다. 나는 원주율이라는 의미로 'PI' 변수에 3.14라는 값을 대입했는데, 다른 개발자는 먹는 'pie'의 의미로 이해하고 개수를 변경해 버릴지도 모르죠.
이때 const를 사용하면 예상하지 못한 변경을 미연에 방지할 수 있습니다.
그리고 값을 변경한다고 표현했는데, 엄밀히 말하면 원시 타입은 "불변성(immuatable)"이라는 성질이 있어서, 값이 변하는 것은 아닙니다. 값이 변경되는 것처럼 보여도 사실은 새로운 저장 공간을 만들고, 변수는 새로 만들어진 공간을 가리키면서 재할당이 이루어지게 됩니다.
number
number 타입은 말 그대로 숫자를 표현하는 자료형입니다.
자연수, 정수, 실수 어떤 수이든 number로 표현합니다.
number 타입 중 조금 독특한 녀석이 하나 있는데, NaN(Not a Number)라는 타입입니다.
숫자 타입이지만 숫자가 아닌 값을 나타냅니다.
예를 들면 0을 0으로 나눈 결과 같은 거죠.
이 녀석도 숫자라서, 1 + NaN처럼 연산에 사용할 수는 있습니다.
다만 결과가 NaN으로 나올 뿐입니다.
bigint
number 타입은 표현할 수 있는 범위가 제한되어 있습니다. 최대 $2^{53}-1$까지만 표현할 수 있습니다.
bigint는 이보다 큰 정수를 표현하기 위한 타입입니다.
정수 리터럴 뒤에 n을 붙이거나 BigInt() 함수를 통해 선언할 수 있습니다.
const theBigInt = 9007199254740992n;
cosnt alsoTheBigInt = BingInt("9007199254740992");
typeof()
typeof() 메서드는 객체가 어떤 타입의 자료형인지를 알려주는 속성입니다.
bigint 타입에 대해 typeof() 메서드를 실행하면 bigint라는 결과가 나옵니다. number와는 다른 타입이라는 것을 보여줍니다.
boolean
boolean은 참과 거짓을 표현하는 자료형입니다.
1 > 2는 거짓이죠. 이런 결과를 나타낼 때 사용됩니다.
true와 false, 두 종류가 있습니다.
특정 조건을 만족해야만 동작하는 if문에 주로 사용합니다.
let ThisisTrue = true; //참
let ThisisFalse = false; //거짓
//괄호 안의 값이 true이면 "It's true."를 출력
if(ThisisTrue) {
console.log("It's true.");
}
재미있는 점은 숫자도 boolean 타입처럼 이용할 수 있다는 점입니다.
0은 false로, 이외의 수는 true로 취급합니다.
string
string은 문자열을 나타내는 타입입니다.
큰 따옴표나 작은 따옴표로 감싸서 나타냅니다.
let animal = 'dog';
string 타입 변수는 인덱스가 있습니다.
let animal = 'dog';
animal[0]; //'d'
animal[1]; //'o'
animal[2]; //'g'
간단한 string 메서드
"엥, 아까는 원시 타입이 메서드가 없는 자료형이라 하지 않았나요?"
원시 타입은 직접적으로 메서드를 가지지 않지만, 자바스크립트는 일시적으로 객체 래퍼(Object Wrapper)를 생성하여 해당 메서드를 사용할 수 있도록 합니다. 자바스크립트는 객체지향 언어이기 때문에 원시 타입을 객체처럼 다룰 수 있도록 하는 것이죠.
trim()
문자열 양 끝에 있는 공백문자를 모두 지워줍니다.
let greeting = " Hello! ";
greeting.trim();
//"Hello!"
toUpperCase(), toLowerCase()
알파벳 문자열을 대문자, 소문자로 변환합니다.
let greeting = "hello!";
greeting.toUpperCase();
//"HELLO"
let warning = "DO NOT TOUCH"
warning.toLowerCase();
//"do not touch"
"typeof는 괄호를 사용하지 않고, toUpperCase()는 괄호를 사용하는데 차이가 무엇인가요?"
괄호를 사용하지 않은 것은 '속성(property)'입니다.
속성은 객체가 가지는 성질을 말합니다.
typeof 속성은 객체의 '자료형' 값을 반환하고, length 속성은 객체의 '길이' 값을 반환합니다.
괄호를 사용한 것은 '메서드(method)'로, 실제로 함수입니다.
toUpperCase()는 객체가 가지는 어떤 정보를 반환하는 것이 아니라, 함수로 어떤 동작을 하여 만들어 낸 결과를 반환합니다.
indexOf()
함수의 인자로 준 문자열과 일치하는 항목의 시작 인덱스를 반환합니다.
일치하지 않으면 -1을 반환합니다.
let animal = "elephant"
animal.indexOf("e") //0
animal.indexOf("ant") //5
animal.indexOf("u") // -1
replace
문자열을 교체합니다.
let animal = "elephant"
animal.replace("ele", "abc") //"abcphant"
문자열 템플릿(string template)
문자열과 변수를 조합해서 어떤 문장을 만들고 싶습니다.
let apples = 5;
"You bought " + apples + " apples";
//'You bought 5 apples'
이렇게 + 연산자를 활용해서 이어 붙일 수도 있지만, 조금 더 세련된 '문자열 템플릿'이란 방법이 있습니다.
문자열 템플릿을 사용하려면
1. 표현하고자 하는 문장을 백틱(`)으로 감싸야합니다.
2. 변수는 ${}로 표현합니다. 괄호 안에 변수 이름을 넣습니다.
`You bought ${apples} apples`
//'You bought 5 apples'
그러면 정확히 같은 결과를 얻을 수 있죠.
null
null은 '없다'를 나타냅니다. 어떤 값을 의도적으로 비워둘 때 사용합니다.
boolean 연산에서는 false로 취급합니다.
undefined
undefined는 '정의되지 않음'을 나타냅니다.
문자열을 예로 들면, "dog"의 23번째 문자열은 존재하지 않으므로 undefined입니다.
let animal = "dog";
animal[23]; //undefined
null과 비슷하지만, 다릅니다. null은 정의는 했지만 내용물이 존재하지 않는다는 것을 나타냅니다.
undefined는 정의조차 되지 않은 상태를 나타냅니다.
// 정의되지 않고 초기화된 적도 없는 bar
bar; //ReferenceError: bar is not defined
// 존재하지만 값이나 자료형이 존재하지 않는 foo
let foo = null;
foo; //null
symbol
symbol은 심볼은 객체에 속성을 추가할 때 고유한 키를 부여하여 다른 코드와 충돌하지 않도록 하는 타입입니다.
일반적으로는 같은 값을 저장하면 비교했을 때 같은 값으로 인식합니다.
let num1 = 1;
let num2 = 1;
num1 == num2; //true
하지만 symbol 타입은 각 객체마다 고유한 id가 있어서 다른 값으로 인식합니다.
let mySymbol1 = Symbol(1);
let mySymbol2 = Symbol(2);
mySymbol1 == mySymbol2; //false
'프로그래밍 > Javascript' 카테고리의 다른 글
「웹해킹을 위한 자바스크립트(Javascript) 훑어보기」- 6. 전개(spread)와 분해 (0) | 2023.07.17 |
---|---|
「웹해킹을 위한 자바스크립트(Javascript) 훑어보기」- 5. 콜백(callback) (0) | 2023.07.11 |
「웹해킹을 위한 자바스크립트(Javascript) 훑어보기」- 4. 함수 (0) | 2023.07.09 |
「웹해킹을 위한 자바스크립트(Javascript) 훑어보기」- 3. 데이터 구조(배열, 객체, 반복) (0) | 2023.07.06 |
「웹해킹을 위한 자바스크립트(Javascript) 훑어보기」- 2. 출력, 참과 거짓(truthy and falsy) (0) | 2023.07.05 |