자바스크립트는 HTML파일에 포함되어 사용된다. HTML처럼 단순히 보여주는 차원을 넘어 프로그래밍이 가능하다.
인터프리터 방식으로 OOP를 기반으로 함수, 클래스를 사용할 수 있고 상속도 가능하다. 그런데 인터프리터는 구체적으로 어떻게 동작하지? 인터프리터 과정은 실시간으로 바이트 코드를 행 별로 읽어서 수행되므로, 컴파일로 수행하는 것보단 빠를 수 있겠지만 런타임 시 코드 라인을 읽어서 수행하다 보니 속도가 많이 빠르지는 않다. 대표적인 인터프리터 언어는 JavaScript, Python 등이 있다
일반 언어처럼 변수 선언 시 숫자나 문자를 자동 인식하므로 데이터 형을 설정하지 않아 초보자에게 편리함을 제공한다.
하지만 소스가 노출되어 보안기능이 약하다는 점과 데이터베이스 프로그래밍을 할 수 없다는 단점도 있다. 하지만 데이터베이스 연동 프로그래밍은 별도의 platform을 이용하면(Node,js) 서버 사이드에서도 가능하다.
브라우저의 JVM(Java Virtual Machine)에 의해 수행된다.
■ 자바스크립트 기본 형태
• HTML 문서 내에 작성할 때 <SCRIPT> 자바스크립트 코드 </SCRIPT>
• HTML 문서 외부에 따로 둘 때 <SCRIPT SRC=“파일명.js”></SCRIPT> 확장자는 js이고 텍스트 문서이다. 다른 사이트의 js 파일도 가능하다 (https://www.acorn.com/abc.js) 웹 문서를 간결하게 해주며, 여러 문서가 공통으로 js 파일을 사용할 수 있다
• 자바스크립트를 이해하지 못하는 브라우저를 위해 주석을( <!-- --> )를 둘러 준다. <SCRIPT > <!-- 자바스크립트 코드 --> </SCRIPT>
|
■ 자바스크립트 위치 • HEAD 태그 내에 <HEAD><title>~~</title> <SCRIPT> 자바스크립트 코드 </SCRIPT> </HEAD> • BODY 태그 내에 <HEAD><title>~~</title></HEAD> <BODY> <SCRIPT> 자바스크립트 코드 </SCRIPT> </BODY> |
window 객체는 자바스크립트의 브라우저 내장 객체의 최상위 객체로서 전체 윈도우에[ 적용될 내용들을 가지고 있으며
frame 문서 내에서 자식 윈도우 각각에 대한 윈도우 객체들도 갖고 있다. window 객체가 가지고 있는 종속 객체에 대해 알아보자.
location 객체 : 현재의 URL을 가지고 있다.
history 객체 : 사용자가 이전에 방문한 URL을 표현하는 기능을 가지고 있다.
document 객체 : 제목, 배경색, 폼에 대한 속성을 가지고 있는데 현재의 문서에 대한 내용을 가지고 있다.
document의 속성은 주로 문서의 내용을 가지고 있다. location, history, document 들은 문서 내의 내용을 기초로 생성된다.
간단 예제
1) location.href = "http://www.daum.net" //다음의 위치를 링크시켜준다.
2) document.title="제목!" //다음의 문서 제목을 "제목!" 이라고 표현해준다.
3) document.fgColor = #f0f0f0 //문서의 전경색의 색상을 위 RGB 코드로 표시해준다.
4) document.bgColor = $ffffff //문서의 배경색의 색상을 위 RGB 코드로 표시해준다.
5) history.length = 7
이를 이용해서 이전에 홈페이지 방문여부를 알 수 있다. 이것은 history 객체가 사용자가 이전에 URL에 방문한 기록을 가지고 있기 때문이다.
-------------------------------------------------------------------------------------------------------------------------------------------
모던 JavaScript 튜토리얼 https://ko.javascript.info/
-------------------------------------------------------------------------------------------------------------------------------------------
변수(variable)란?
https://velog.io/@rimo09/%EC%9E%90%EB%B0%94%EC%8A%A4%ED%81%AC%EB%A6%BD%ED%8A%B8-%EB%B3%80%EC%88%98
-------------------------------------------------------------------------------------------------------------------------------------------
Primitive Type(원시 타입) vs Reference Type (참조 타입)
JavaScript는 원시 타입과 참조 타입이라는 두 가지 자료형을 제공하며 Object를 제외한 모든 것들은 Primitive한 성격을 갖고 있다.
- Primitive Type : 데이터의 실제 값 할당
- Reference Type : 데이터의 위치 값만 할당
1) Primitive Type (원시타입)
원시 타입의 데이터는 변수에 할당이 될 때 메모리 상에 고정된 크기로 저장이 되고 해당 변수가 원시 데이터 값을 보관한다. 원시 타입 자료형은 모두 변수 선언, 초기화, 할당 시 값이 저장된 메모리 영역에 직접적으로 접근한다. 즉, 변수에 새 값이 할당될 경우, 변수에 할당된 메모리 블럭에 저장된 값을 바로 변경한다.
Primitive Type의 종류
- Boolean
- number
- String
- null
- undefined
1.2 Primitive Type의 변수 복사
각 변수 간에 원시 타입 데이터를 복사할 경우, 데이터의 값이 복사된다.
let x = 100;
let y = x;
x = 99;
console.log(y); // 100;
데이터 값을 복사하기 때문에 console을 찍기 전, x를 99로 바뀌었지만 이전의 값인 100을 복사해두었기 때문에 100이 찍히는 것을 볼 수 있다.
원시타입의 작동원리 : 자바스크립트에서 원시타입을 선언하면, 이는 stack에 저장된다. stack이란 LIFO(Last In First Out) 구조를 가진 자료구조이다. 저장된 원시타입은 식별자를 통해 접근할 수 있고, 원시 데이터와 함께 스택에 저장된다.
const numOne = 50; const numTwo = 50;
위와 같이 같은 값을 가진 두개의 변수가 선언 및 할당되었을 때, numOne 이 값과 함께 스택에 push되고, 그 위에 numTwo 가 값과 함께 stack에 push 된다. 두 개의 공간이 별도로 생성된다.
이때 numOne의 값을 변경해도 numTwo 에는 값의 변화가 없다.
let numOne = 50;
let numTwo = numOne;
numOne = 100;
console.log(numOne); // 100
console.log(numTwo); // 50
let a = 'Hello';
let b = a;
console.log(a); // Hello
console.log(b); // Hello
a = "World";
console.log(a); // World
console.log(b); // Hello
위의 코드는 Primitive type 중 하나인 string을 이용한 코드이다. 코드를 보면 먼저 a에 'Hello'라는 값을 할당해 주었고 같은 값을 b에 할당해 주었다. 그 후에 a의 값을 'World'로 변경을 시켜도 b 값에는 영향이 없다.
2) Reference Type (참조 타입)
참조 타입의 데이터는 크기가 정해져 있지 않고 변수에 할당이 될 때 값이 직접 해당 변수에 저장될 수 없으며 변수에는 데이터에 대한 참조만 저장된다. 변수의 값이 저장된 heap 메모리의 주소값을 저장한다. 참조 타입은 변수의 값이 저장된 메모리 블럭의 주소를 가지고 있고 자바스크립트 엔진이 변수가 가지고 있는 메모리 주소를 이용해서 변수의 값에 접근한다.
Referece Type의 종류
- Object ( array, function, object )
Reference Type의 변수 복사 : 각 변수 간에 참조 타입 데이터를 복사할 경우, 데이터의 참조가 복사된다.
let x = { count : 100 };
let y = x;
x.count = 99;
console.log(y); // 99
변수 x와 y는 동일한 참조를 담고 있다. 따라서 동일한 객체를 가리키게 된다.
참조(reference)타입의 작동 : 참조 타입 데이터는 원시타입과 다르게 동적이다(dynamic). 다시말해 고정된 크기를 가지지 않는다. 대부분은 객체(object) 로 치환되며, method를 가진다. 예를 들어 array, function, object, date 등 많은 참조 타입 데이터가 있다.
원시타입과 객체타입의 차이
차이점은 참조타입 데이터를 저장해야할 때 생긴다. 변수를 선언 후 참조타입의 데이터를 할당하려 할 때, 값은 해당 변수에 직접적으로 할당되지 않는다. 해당 변수에 저장되는 값은 메모리에 저장되어 있는 참조타입 값의 주소이다.
위 그림을 보면, 두 개의 자료구조가 있다. stack과 heap이다. 객체를 선언 및 할당했다고 가정했을 때, 해당 객체는 heap에 저장된다. 그리고 이의 포인터는 stack에 저장된다. 포인터란 해당 객체의 메모리 주소 값을 가리키는 변수이다.
const obj1 = { name: 'tom', age: 25 };
const obj2 = obj1;
obj1.age = 28;
console.log(obj2.age); // 28
obj1 이란 변수를 선언하였고, 객체를 할당하였다. 이후에 이전 원시타입과 같이 obj2 를 선언 후 obj1 를 이에 할당하였다. 그렇다면 heap에 새로운 객체가 생성될까? 아니 생기지 않는다. 해당 객체가 이미 heap에 존재하는 동안 obj1 과 obj2 는 같은 객체를 가리킨다. 다른 차이점은 obj1 의 프로퍼티를 업데이트 할 때 볼 수 있다. 위의 코드와 같이 콘솔로 찍어보면 obj2 의 프로퍼티 또한 변경된 것을 볼 수 있다. 이는 obj1 과 obj2 가 heap에 있는 같은 객체를 가리키고 있어, 서로 영향을 주기 때문이다.
참조 타입의 변수들은 데이터 복사가 일어날 때 값이 담긴 주소값을 바로 복사하지 않고, 값이 담긴 주소 값들로 이루어진 묶음을 가리키는 주소값을 복사한다.
let obj1 = { a: 1, b: "bbb" };
let obj2 = obj1;
obj2.a = 20;
console.log(obj1.a); // 20
위의 코드에서, obj2는 obj1이 가리키는 데이터 묶음의 주소를 복사한다. (같은 객체를 보고 있음) 그러므로 obj2에서 프로퍼티의 값을 변경하면, 같은 객체의 주소를 가지고 있는 obj1에서도 값이 변하게 되는 것이다.
하지만
let obj1 = { a: 1, b: "bbb" };
let obj2 = obj1;
obj2 = { a: 20, b: "cc" };
console.log(obj1.a); // 1
이처럼 복사 후 obj2에 새로운 객체를 할당해 주게 되면 메모리 데이터 영역의 새 공간에 새로운 객체가 저장되고 그 주소를 변수 영역의 obj2에 저장하게 된다. 즉 obj1과 obj2가 다른 객체를 가리키게 되므로 obj1이 가리키는 값은 달라지지 않는다.
이를 통해 알 수 있는 점은, 참조형 데이터를 가변값이라 할 때의 "가변"은 참조형 데이터 자체를 변경할 때(두 번째 경우)가 아니라 그 내부의 프로퍼티를 변경할 때(첫 번째 경우)에만 성립한다는 것이다!!!