자바스크립트의 배열은 C나 자바의 배열과 같은 기능을 하는 객체지만 이들과 달리 크기를 지정하지 않아도 되고, 어떤 위치에 어느 타입의 데이터를 저장해도 에러가 발생하지 않는다.
1. 배열 리터럴
var colorArr = ['red', 'yello', 'green'];
console.log(colorArr[0]);
console.log(colorArr[1]);
console.log(colorArr[2]);
배열 리터럴은 새로운 배열을 만드는 데 사용하는 표기법이다. 대괄호( `` [ ] `` )를 사용한다.
대괄호 안에 인덱스 값을 넣어서 배열의 각 원소에 접근할 수 있다. (인덱스는 0부터 시작)
2. 배열의 요소 생성
var emptyArr = []; // 대괄호만 사용하면 빈 배열이 생성됨
console.log(emptyArr[0]); //요소가 없기 때문에 undefined가 출력됨(값이 없는 원소에 접근할 경우 undefined가 출력됨)
//데이터 타입에 상관없이 추가 가능
emptyArr[0] = 100;
emptyArr[3] = 'eight';
emptyArr[7] = true;
console.log(emptyArr);
console.log(emptyArr[2]); // 값이 할당되지 않은 요소는 undefined 값을 기본으로 가짐
객체의 프로퍼티처럼 배열도 동적으로 원소를 추가할 수 있다. 값을 순차적으로 넣을 필요 없이 아무 인덱스 위치에나 값을 동적으로 추가할 수 있다. 대신 배열도 값이 없는 원소에 접근할 경우 ``undefined``가 출력된다.
원소를 3개 추가했지만 배열의 인덱스 중 가장 큰 값을 기준으로 배열의 크기가 정해지기 때문에 8개의 배열 요소 값이 출력된다.
3. 배열의 length 프로퍼티
// 1. length 프로퍼티 자동 변경
var arr = [];
console.log(arr.length); //빈배열일 경우 length 프로퍼티값은 0
arr[0] = 0;
arr[1] = 1;
arr[2] = 2;
arr[100] = 100;
console.log(arr.length);
// 2. length 프로퍼티의 명시적 변경
var arr = [0, 1, 2];
console.log(arr.length);
arr.length = 5;
console.log(arr);
arr.length = 2; // length 길이 이후의 요소들은 삭제됨
console.log(arr);
console.log(arr[2]);
자바스크립트의 모든 배열에는 ``length`` 프로퍼티가 있다. (자바스크립트에서는 배열에서 사용 가능한 다양한 표준 메서드를 제공하는데, 이 배열 메서드들은 ##length## 프로퍼티를 기반으로 동작한다.) ``length``프로퍼티는 배열 내의 가장 큰 인덱스에 1을 더한 값으로 배열의 원소 개수를 나타낸다. (실제로 배열에 존재하는 원소 개수와 항상 일치하는 것은 아니다. 메모리도 항상 @@length@@만큼 할당되지 않는다.) 배열의 가장 큰 인덱스 값이 변하면 ``length``또한 자동으로 변경된다. 빈 배열일 경우에는 ``length`` 프로퍼티 값은 ``0``이된다.
- ##push( )## 메서드 : 인수로 넘어온 항목을 배열 끝에 추가 → 배열의 현재 ``length``값 위치에 새로운 원소 추가
4. 배열과 객체
// 배열
var colorsArray = ['red', 'yellow', 'green'];
console.log(colorsArray[0]);
console.log(colorsArray[1]);
console.log(colorsArray[2]);
// 객체
var colorsObj = {
'0' : 'red',
'1' : 'yellow',
'2' : 'green'
};
console.log(colorsObj[0]); // 원래 colorsObj['0']이 맞음([]연산자 내에 숫자가 사용될 경우 문자열 형태로 자동변환)
console.log(colorsObj[1]);
console.log(colorsObj[2]);
// typeof 연산자 비교
console.log(typeof colorsArray);
console.log(typeof colorsObj);
// length 프로퍼티
console.log(colorsArray.length);
console.log(colorsObj.length); // 객체에는 length 프로퍼티가 존재하지 X
// 배열 표준 메서드
colorsArray.push('blue');
colorsObj.push('blue');
배열과 객체의 유사점과 차이점을 보여주는 예제이다.
``typeof``로 확인해보면 배열과 객체가 모두 ``object``인 것을 확인할 수 있다.
배열이 아닌 객체에서는 ``length`` 프로퍼티가 존재하지 않아서 ``undefined``로 나온다( ``colorsObj`` )
배열이 아닌 객체에서는 ``push( )``와 같은 표준 배열 메서드를 사용할 수 없다.
배열과 객체의 프로토타입 객체가 서로 다르기 때문에 표준 배열 메서드를 사용할 수 없는 것! - 객체의 프로토 타입 : ``Object.prototype`` 객체 - 배열의 프로토 타입 : ``Array.prototype`` 객체 ( ##Array.prototype## 객체의 프로토타입은 ##Object.prototype## )
var emptyArray = []; // 배열 리터럴을 통해 빈 배열 생성
var emptyObj = {}; // 객체 리터럴을 통해 빈 객체 생성
console.dir(emptyArray.__proto__); // 배열의 프로토타입(Array.prototype) 출력
console.dir(emptyObj.__proto__); // 객테의 프로토타입(Object.prototype) 출력
배열과 객체의 프로토타입을 확인할 수 있다.
예제에서 나온 ``emptyArray`` 배열의 프로토타입을 나타내는 ``emptyArray.__proto__``는 ##Array[0]## 객체를 가리키는데, 이는 ##Array.prototype## 객체를 나타낸다. 이 객체 내에 표준 배열 메서드가 있다.
``Array.prototype`` 객체 역시 @@__proto__@@ 프로퍼티가 있으며, 이 값은 @@Object.prototype@@을 가리킨다.
``emptyObj``는 일반 객체이기 때문에 ``__proto__`` 프로퍼티가 ##Object.prototype##을 가리키고 있다.
5. 배열의 프로퍼티 동적 생성
// 배열 생성
var arr = ['zero', 'one', 'two'];
console.log(arr.length);
// 프로퍼티 동적 추가
arr.color = 'blue';
arr.name = 'number_array';
console.log(arr.length);
// 배열 원소 추가
arr[3] = 'red';
console.log(arr.length);
// 배열 객체 출력
console.dir(arr);
배열도 객체이므로, 인덱스가 숫자인 배열 원소 이외에도 객체처럼 동적으로 프로퍼티를 추가할 수 있다.
프로퍼티를 추가해도 배열의 @@length@@ 값은 변하지 않는다. (배열의 가장 큰 인덱스가 변했을 경우만 바뀜)
6. 배열의 프로퍼티 열거
// for in 문
for (var prop in arr){
console.log(prop, arr[prop]);
}
// for문
for(var i=0; i<arr.length; i++){
console.log(i, arr[i]);
}
배열도 객체이므로 ``for in``문을 사용해서 배열 내의 모든 프로퍼티를 열거할 수 있지만, 불필요한 프로퍼티가 출력될 수 있으므로 배열 요소만 출력하려면 @@for@@문을 사용하는 것이 좋다. 위의 코드는 앞서 만들었던 배열을 출력하는 예시이다.
7. 배열 요소 삭제
// 1. delete 연산자를 이용한 배열 프로퍼티 삭제 : 요소값만 undefined로 바뀌고 length는 줄어들지 X
var arr = ['zero', 'one', 'two', 'three'];
delete arr[2];
console.log(arr);
console.log(arr.length);
// 2. splice() 메서드를 이용한 배열 프로퍼티 삭제
var arr = ['zero', 'one', 'two', 'three'];
arr.splice(2, 1);
console.log(arr);
console.log(arr.length);
배열도 객체이므로 배열 요소나 프로퍼티를 삭제하는데 쓰는 ``delete`` 연산자를 사용할 수 있다. 그러나 @@delete@@로 배열의 요소를 삭제하면 해당 인덱스에는 @@undefined@@가 할당되지만 @@length@@값은 줄어들지 않는다.(== 원소 자체를 삭제하지는 않는다.) 이 때문에 보통 배열에서 요소들을 완전히 삭제하는 경우에 ``splice( )``배열 메서드를 사용한다.
``splice(start, deleteCount, item...)``
start : 배열 시작 위치
deleteCount : ``start``에서 지정한 시작 위치부터 삭제할 요소의 수
item : 삭제할 위치에 추가할 요소
8. Array( ) 생성자 함수
// 1. 인자가 1개인 경우 : 인자를 length로 갖는 빈배열 생성
var kim = new Array(3);
console.log(kim); // [undefined, undefined, undefined]
console.log(kim.length);
// 2. 인자가 2개 이상인 경우 : 인자를 요소로 갖는 배열 생성
var bar = new Array(1, 2, 3);
console.log(bar);
console.log(bar.length);
배열은 일반적으로 배열 리터럴로 생성하지만 ``Array( )``생성자 함수로 배열을 생성하는 방법도 있다.
생성자 함수로 배열과 같은 객체를 생성할 때는 반드시 @@new@@ 연산자를 같이 써야 한다.
Array( ) 생성자 함수의 인자에 따른 동작
호출 시 인자가 1개이고 숫자인 경우 : 인자를 ``length``로 갖는 빈 배열 생성
그 외의 경우 : 인자들을 요소로 갖는 배열 생성
9. 유사 배열 객체
var arr = ['bar'];
var obj = {
name: 'kim',
length: 1
};
arr.push('baz');
console.log(arr);
obj.push('baz'); // 유사 배열 객체인 obj는 배열이 아니라 push()메서드를 사용할 수 X
// 유사 배열 객체의 경우 apply()메서드를 사용하면 객체지만 표준 배열 메서드를 사용할 수 있다.
Array.prototype.push.apply(obj, ['baz']);
console.log(obj);
배열 이외에 ``length`` 프로퍼티를 가진 객체를 유사 배열 객체(array-like objects)라고 부른다. 유사 배열은 객체임에도 불구하고 자바스크립트의 표준 배열 메서드를 사용할 수 있다는 것이 특징이다.(arguments 객체나 jQuery 객체가 유사 배열 객체 형태이다.)
유사 배열 객체에서 ``apply( )``메서드를 사용하면 객체지만 표준 배열 메서드를 사용할 수 있다.
객체 생성 * 객체 생성 방법 1) 기본 제공 Object( ) 생성자 함수 이용 2) 객체 리터럴 이용 3) 생성자 함수 이용
객체 프로퍼티 읽기/쓰기/갱신 * 객체의 프로퍼티 접근 방법 1) 대괄호([ ]) 표기법 2) 마침표(.) 표기법
for in문과 객체 프로퍼티 출력
객체 프로퍼티 삭제
참조 타입의 특성
객체 비교
참조에 의한 함수 호출 방식 1) 기본 타입 : Call By Value 2) 참조 타입 : Call By Reference
프로토 타입
데이터 타입
기본 데이터 타입인 ``boolean``, ``number``, ``string``과 특별한 값인 ``null``, ``undefined``를 제외한 나머지를 모두 객체로 취급한다.(기본 데이터 타입을 객체처럼 다루는 것은 가능하다.)
자바스크립트는 느슨한 타입 체크 언어이기 때문에 변수 선언 시 타입을 미리 정하지 않고 ``var``라는 키워드를 사용한다. 어떤 형태의 데이터를 저장하느냐에 따라 해당 변수의 타입이 결정된다. (ES6부터는 변수 선언 시 ``var``외에 @@let@@와 @@const@@예약어 사용 가능) 자바스크립트의 값들은 크게 기본 타입과 참조 타입으로 나뉜다.
1. 기본 타입
자바스크립트에서 기본 타입은 숫자, 문자열, 불린 값, ``null``과 ``undefined``라는 타입이 있다. 기본 타입의 특징은 그 자체가 하나의 값을 나타낸다는 것이다.
기본 타입의 종류
숫자(Number)
문자열(String)
불린 값(Boolean)
null과 undefined
- ##typeof## 연산자 : 피연산자의 타입을 리턴한다.
■ 숫자(Number)
var num = 5 / 2;
console.log(num);
console.log(Math.floor(num));
자바스크립트에서는 모든 숫자를 64bit 부동 소수점 형태로 저장한다. 정수형이 따로 없고 모든 숫자를 실수로 처리하므로 나눗셈 연산을 할 때는 주의해야 한다. (소수부 버리고 싶을 때는 ##Math.floor( )##사용)
■ 문자열(String)
// 문자열 생성
var str = "test";
console.log(str[0], str[1], str[2], str[3]);
// 문자열 수정 불가
str[0] = "T";
console.log(str);
문자열은 `` ' ``나 `` " ``로 생성하며 한번 정의된 문자열은 읽기만 가능하고 수정이 불가능하다. ( ##char##타입과 같이 문자 하나만을 별도로 나타내는 데이터 타입은 존재하지 않는다.) 문자열은 문자 배열처럼 인덱스를 이용해서 접근할 수 있다.
``str[0]``을 변경하려 했지만 변경되지 않는 것을 확인할 수 있다.(에러는 안남)
■ 불린 값(Boolean)
불린 타입은 true와 false 값을 나타낸다.
■ null과 undefined
// null 타입 변수 생성
var nullVar = null;
console.log(typeof nullVar === null);
console.log(nullVar === null);
두타입은 모두 자바스크립트에서 '값이 비어있음'을 나타낸다.
undefined - 타입이자 값을 나타냄 - 자바스크립트 환경 내에서 기본적으로 값이 할당되지 않은 변수는 타입과 값이 모두 ``undefined``
null - null 타입 변수는개발자가 명시적으로 값이 비어있음을 나타내는 데 사용 - null타입은 @@typeof@@연산자를 사용하면 결과값이 @@object@@기 때문에 @@===@@(일치 연산자)을 사용해서 변수의 값을 직접 확인해야 한다.
■ 기본 타입과 표준 메서드
// 기본 타입 변수에서 메서드 호출
// 1. 숫자 메서드 호출
var num = 0.5;
console.log(num.toExponential(1)); // toExponential()는 표준 숫자형 메서드로, 숫자를 지수 형태의 문자열로 변환
// 2. 문자열 메서드 호출
console.log("test".charAt(2)); // charAt()은 표준 문자열 메서드로, 문자열에서 인자로 받은 위치에 있는 문자를 반환
자바스크립트에서는 숫자, 문자열, 불린값 등 기본 타입을 위해 정의된 표준 메서드가 있고, 이들을 객체처럼 호출할 수 있다. (기본 타입은 객체가 아니기 때문에) 기본 타입의 값들에 대해서 객체 형태로 메서드를 호출할 경우, 메서드 처리 순간에 객체로 변환된 뒤 각 타입별 표준 메서드를 호출하게 된다. 메서드 호출이 끝나면 다시 기본값으로 바뀐다.
2. 참조 타입(객체 타입)
자바스크립트에서 기본 타입을 제외한 모든 값은 객체다. (배열, 함수, 정규표현식 등도 모두 자바스크립트 객체로 표현된다.) 객체는 단순히 ``이름(key) : 값(value)``형태의 프로퍼티들을 저장하는 컨테이너로서 (자료구조의 해시(hash)와 유사) 기본 타입이 하나의 값만을 가지는데 비해, 참조 타입인 객체는 여러 개의 프로퍼티들을 포함할 수 있고, 프로퍼티로 기본 타입의 값을 포함하거나, 다른 객체를 가리킬 수도 있다. 객체의 프로퍼티는 함수로 포함할 수 있으며, 자바스크립트에서는 이러한 프로퍼티를 메서드라고 부른다.
■ 객체 생성
자바 스크립트에서는 클래스라는 개념이 없고, 객체 리터럴이나 생성자 함수 등 별도의 생성 방식이 존재한다.
객체 생성 방법
기본 제공 ``Object( )``객체 생성자 함수를 이용
객체 리터럴을 이용
생성자 함수를 이용
1) 기본 제공 Object( ) 생성자 함수 이용
// Object()를 이용해서 빈 객체인 kim 생성
var kim = new Object();
// 객체 프로퍼티 생성
kim.name = 'kim';
kim.age = 20;
kim.gender = "male";
자바스크립트에서는 객체를 생성할 때, 내장 ``Object( )``생성자 함수를 제공한다.
2) 객체 리터럴 이용
//객체 리터럴 방식으로 객체 kim 생성
var kim = {
name : 'kim',
age : 20,
gender : 'male'
};
객체 리터럴이란 객체를 생성하는 표기법을 의미한다. 중괄호( ``{ }`` )를 이용해서 객체를 생성하며, 안에 아무것도 적지 않으면 빈 객체가 생성된다. ``프로퍼티 이름 : 프로퍼티 값``형태로 표기하면 해당 프로터피가 추가된 객체를 생성할 수 있다.
프로퍼티 이름 : 문자열이나 숫자
프로퍼티 값 : 자바스크립트의 값을 나타내는 어떤 표현식도 올 수 있다. (값이 함수일 경우에는 메서드라고 부름)
3) 생성자 함수 이용 함수를 통해서도 객체를 생성할 수 있다. 이렇게 객체를 생성하는 함수를 생성자 함수라고 부른다.
■ 객체 프로퍼티 읽기/쓰기/갱신
var kim = {
name : 'kim',
major : 'computer science'
};
// 객체 프로퍼티 읽기
// 대괄호 표기법의 경우 접근하려는 프로퍼티 이름이 문자열이여야 하므로 주의한다.
// (문자열이 아닐경우 undefined 출력)
console.log(kim['name']); //대괄호 표기법
console.log(kim.name); //마침표 표기법
console.log(kim.nickname);
// 객체 프로퍼티 갱신
kim['major'] = 'computer engineering'; //대괄호 표기법
kim.major = 'computer engineering'; //마침표 표기법
console.log(kim.major);
console.log(kim['major']);
// 객체 프로퍼티 동적 생성
kim.age = 20;
console.log(kim.age);
// 대괄호 표기법만 사용해야 할 경우
// 접근하려는 프로퍼티가 표현식이거나 예약어일 경우 대괄호 표기법만을 이용해서 접근해야 한다.
kim['full-name'] = "kim bab"; // '-' 연산자가 있는 표현식
console.log(kim['full-name']);
console.log(kim.full-name); // kim.full - name 으로 취급했기 때문에 NaN이 출력됨
console.log(kim.full);
console.log(name);
객체는 새로운 값을 가진 프로퍼티를 생성하고, 생성된 프로퍼티에 접근해서 해당 값을 읽거나 원하는 값으로 프로퍼티의 값을 갱신할 수 있다. 객체의 프로퍼티에 값을 할당할 때, 프로퍼티가 이미 있을 경우에는 해당 프로퍼티의 값이 갱신되지만, 없을 경우에는 새로운 프로퍼티가 동적으로 생성된 후 값이 할당된다.
대괄호 표기법에서 접근하려는 프로퍼티 이름을 문자열 형태로 만들지 않으면 @@undefined@@값이 출력되므로 주의한다.(프로퍼티 이름을 문자열 형태로 만들지 않으면 모든 자바스크립트 객체에서 호출 가능한 ##toString( )##이라는 메서드를 자동으로 호출해서 이를 문자열로 바꾸려는 시도를 한다. 만약 객체에 없는 프로퍼티에 접근하는 경우는 ##undefined##값이 출력된다.) 또한 접근하려는 프로퍼티가 표현식이거나 예약어일 경우에는 대괄호 표기법만을 사용해야 한다.
NaN(Not a Number) 값 : 수치 연산을 해서 정상적인 값을 얻지 못할 때 출력되는 값. ex) 1 - 'hello' = NaN
객체의 프로퍼티 접근 방법
대괄호([ ])표기법
마침표(.) 표기법
■ for in 문과 객체 프로퍼티 출력
// 객체 리터럴을 통한 kim 객체 생성
var kim = {
name : 'kim',
age : 20,
major : 'computer science'
};
// for in문을 이용한 객체 프로퍼티 출력
for(var i in kim){
console.log(i, kim[i]);
}
// 변수를 미리 선언할 경우 아래와 같이 사용
var i;
for (i in kim) {
console.log(i, kim[i]);
}
``for in``문을 사용하면, 객체에 포함된 모든 프로퍼티에 대해 루프를 수행할 수 있다. 예를 들어 위의 코드는 변수 `` i ``에 ``kim`` 객체의 프로퍼티가 하나씩 할당된다. `` i ``에 할당된 프로퍼티 이름을 이용해서 ``kim[i]``와 같이 대괄호 표기법을 이용해서 프로퍼티 값을 출력한 것이다.
■ 객체 프로퍼티 삭제
// 객체 리터럴을 통한 kim 객체 생성
var kim = {
name : 'kim',
nickname : 'bab'
};
console.log(kim.nickname);
delete kim.nickname; // nickname 프로퍼티 삭제
console.log(kim.nickname); // 프로퍼티가 삭제되었으므로 undefined가 출력됨
delete kim; // 객체는 삭제할 수 X. 프로퍼티만 삭제 가능하다.
console.log(kim.name);
``delete``연산자를 이용해서 객체의 프로퍼티를 삭제할 수 있다.
객체의 프로퍼티만 삭제 가능하고 객체 자체를 삭제하지는 못한다.
``delete kim``을 했지만 객체는 삭제되지 않기 때문에 ``kim.name``을 했을 때 여전히 프로퍼티가 출력되는 것을 확인할 수 있다.
3. 참조 타입의 특성
// 객체 리터럴 방식으로 objA 생성
// 변수 objA는 객체 자체를 저장하고 있는 것이 아니라 생성된 객체를 가리키는 참조값을 저장한다.
var objA = {
val : 40
};
//objB에도 objA의 참조값이 저장됨(동일한 객체를 가리킴)
var objB = objA;
console.log(objA.val);
console.log(objB.val);
// 서로 같은 객체를 가리키기(참조하기) 때문에 objB를 바꿔도 objA가 함께 바뀜
objB.val = 50;
console.log(objA.val);
console.log(objB.val);
참조 타입의 경우 객체의 모든 연산이 실제 값이 아닌 참조값으로 처리된다.
``objB``와 ``objA``모두 참조값을 가지고 있기 때문에 ``objB``를 변경하면 ``objA``도 함께 바뀌는 것을 확인할 수 있다.
■ 객체 비교
var a = 100;
var b = 100;
var objA = { value: 100 };
var objB = { value: 100 };
var objC = objB;
console.log(a == b);
console.log(objA == objB);
console.log(objB == objC);
동등 연산자( ``==`` )를 사용하여 두 객체를 비교할 때도 객체의 프로퍼티 값이 아닌 참조값을 비교한다.
기본 타입의 경우는 값 자체를 비교해서 일치 여부를 판단하지만 객체와 같은 참조 타입의 경우는 참조값이 같아야 true가 된다.
■ 참조에 의한 함수 호출 방식
기본 타입과 참조 타입의 경우는 함수 호출 방식이 다르다.
기본 타입 : Call By Value 방식(값에 의한 호출) 함수를 호출할 때 인자로 기본 타입의 값을 넘길 경우, 호출된 함수의 매개변수로 복사된 값이 전달된다. 매개변수를 이용해 값을 변경해도 실제로 호출된 변수의 값은 변경되지 X
참조 타입 : Call By Reference 방식(참조에 의한 호출) 함수를 호출할 때 인자로 참조 타입의 객체를 전달할 경우 인자로 넘긴 객체의 참조값이 그대로 함수 내부에 전달된다.(객체의 프로퍼티 값이 복사되는 것이 X) 그래서 함수 내부에서 참조값을 이용해 인자로 넘긴 원래 객체의 값을 변경할 수 있다.
var a = 100;
var objA = { value: 100 };
function changeArg(num, obj){
num = 200;
obj.value = 200;
console.log(num);
console.log(obj);
}
changeArg(a, objA);
console.log(a);
console.log(objA);
Call by Value방식과 Call By Reference 방식의 차이점을 보여주는 예제이다.
참조 타입의 객체를 인자로 넣어야 실제 객체의 프로퍼티 값이 함수 호출 후에도 적용된다.
4. 프로토 타입
자바스크립트의 모든 객체는 자신의 부모 역할을 하는 객체와 연결되어 있다.(=모든 객체는 숨겨진 Link인 Prototype을 가진다. 이 링크는 해당 객체를 생성한 생성자의 프로토 타입 객체를 가리킨다. 이 링크를 ECMAScript에서는 ##[[Prototype]]##이라고 표현한다.) 객체 지향의 상속 개념과 같이 부모 객체의 프로퍼티를 자신의 것처럼 쓸 수 있다는 특징이 있다. 이러한 부모 객체를 프로토타입(프로토타입 객체)이라고 한다.
var kim = {
name: 'kim',
age: 30
};
console.log(kim.toString());
console.dir(kim);
``kim``객체에는 ``toString( )``메서드가 없는데도 결과가 출력된다.
에러가 발생하지 않는 이유는 ``kim``객체의 프로토 타입에 ``toString( )``메서드가 이미 정의되어 있기 때문이다.
위의 ``[[Prototype]]``프로퍼티가 ``kim``객체의 부모인 프로토타입 객체를 가리킨다. ``kim``객체는 자신의 부모 객체를 ``[[Prototype]]``라는 내부 프로퍼티로 연결하고 있는 것이다. (ECMAScript 명세서에는 자바스크립트의 모든 객체는 자신의 프로토 타입을 가리키는 ##[[Prototype]]##이라는 숨겨진 프로퍼티를 가진다고 설명한다.) 크롬 브라우저에서는 [[Prototype]]를 __proto__라고 표시하기도 한다.
객체 리터럴 방식으로 생성된 객체의 경우 ``Object.prototype``객체가 프로토타입 객체가 된다. 위에서는 ##[[Prototype]]## 프로퍼티가 가리키는 객체가 ##Object.prototype##이며, 모든 객체에서 호출 가능한 자바스크립트 기본 내장 메서드가 포함되어 있다.(자바스크립트 표준 메서드로서 ECMAScript 명세서에 정의되어 있다.)
객체를 생성할 때 결정된 프로토타입 객체는 임의의 다른 객체로 변경하는 것도 가능하다. (부모 객체를 동적으로 바꿀 수도 있다.)
var newWin = window.open("", "", "width=300, height=300") newWin.close( )
confirm( )
확인 , 취소 가 있는 확인 창을표시
var result = window.confirm("보여줄 메시지") // result에 선택한 값이 저장됨(확인은 true)
focus( )
현재 창에 포커스를 부여
moveBy( )
현재 창을 지정한 크기만큼 이동시킴 (현재 위치를 기준으로 가로로 x픽셀, 세로로 y픽셀 만큼 이동)
var newWin = window.open("", "", "width=300, height=300") newWin.moveBy(500,500)
moveTo( )
현재 창을 지정한 좌표로 이동시킴 (화면의 왼쪽 위 모서리를 기준으로 가로로 x픽셀, 세로로 y픽셀만큼 이동)
var newWin = window.open("", "", "width=300, height=300") newWin.moveTo(0,0) //창을 화면 왼쪽 위로 옮김
open( )
새로운 창(새 탭)을 연다.
■ 매개변수 (전부 선택, 필수 X) 1번째 매개변수 : 문서나 사이트 주소(생략하면 빈문서) 2번째 매개변수 : 새 창의 Target이나 윈도우 이름 3번째 매개변수 : 알림창으로 표시할 때의 너비나 높이, 위치(px값, 높이나 너비의 최소값은 100 , left 는 화면의 왼쪽 가장자리 기준, top 은 위쪽 가장자리 기준)
window.open("https://www.daum.net") window.open() //빈 문서 window.open("https://www.daum.net", "_self") // 현재 창에 새창 표시 window.open("https://www.daum.net", "", "left=0, top=0, width=300, height=300")
postMessage( )
다른 창으로 메시지 전달
print( )
현재 문서를 인쇄
window.print( )
prompt( )
프롬프트 창에 입력한 텍스트를 반환
1번째 매개변수(선택) : 화면에 표시할 메시지 2번째 매개변수 : 텍스트 입력필드에 기본으로 전달할 문자열
window.prompt("표시할 메시지", "default 문자열")
resizeBy( )
지정한 크기만큼 현재 창 크기를 조절 (현재 브라우저 창의 크기를 기준으로 너비와 높이에 값을 더해줌)
var newWin = window.open("", "", "width=300, height=300") newWin.resizeBy(100,100) //가로 세로 길이 100픽셀씩 늘림 newWin.resizeBy(-100,-100) //가로 세로 길이 100픽셀씩 줄임
resizeTo( )
동적으로 브라우저 창의 크기 조절(최종 크기를 지정) resizeBy( ) 함수에서는 음수 값을 사용할 수 있지만 resizeTo( ) 함수 에서는 음수 값을 지정할 수 X
var newWin = window.open("", "", "width=300, height=300") newWin.resizeTo(200,200) // 창의 (최종) 크기를 가로, 세로 200px로 지정
scroll( )
문서에서 특정 위치로 스크롤
scrollBy( )
지정한 크기만큼씩 스크롤
scrollTo( )
지정한 위치까지 스크롤
setCursor( )
현재 창의 커서를 변경
showModalDialog( )
모달 창(Modal Window)을 표시
모달 창 : 이벤트 정보나 공지 내용 등을 표시하기 위해 현재 브라우저 창 위에 띄우는 새로운 창. 일반적인 알림 창이 웹 브라우저 창을 새로 여는 것이라면 모달 창은 문서 소스 안에 <div> 태그를 사용해 삽입하고 레이어로 표시한 창이다. 알림창을 차단하더라도 모달 창은 화면에 표시 가능
sizeToContent( )
내용에 맞게 창 크기를 맞춤
stop( )
로딩중지
window.stop( )
Navigatoar 객체
Navigator 객체에는 웹 브라우저와 관련된 정보가 담겨있다.(브라우저 버전이나 플랫폼(OS) 버전 등)사용자가 수정할 수 없고 볼 수만 있다.
■ 렌더링 엔진(Rendering Engine)
레이아웃 엔진(Layout Engine)이라고도 한다. 브라우저에서 웹 문서를 화면에 표시하기 위해 웹 문서의 태그와 스타일을 해석하는 프로그램이다. 웹 브라우저마다 내장된 렌더링 엔진이 다르기 때문에 표준화되지 않은 CSS3 속성 앞에 --webkit- 또는 -oz- 같은 접두어(prefix)를 붙여서 사용자가 접속한 브라우저에 맞게 렌더링 한다. 자바스크립트 소스를 해석하는 자바스크립트 엔진도 내장되어 있는데 이것 역시 웹 브라우저마다 다르다.
[참고] 브라우저별 렌더링 및 자바스크립트 엔진
브라우저
렌더링 엔진
자바스크립트 엔진
크롬(Chrome)
블링크(Blink)
버전 28이후에 블링크로 바뀌었지만 블링크도 기존의 웹킷 엔진을 기반으로 하기 때문에 렌더링 엔진은 AppleWebkit으로 나온다.
V8
파이어 폭스(Firefox)
게코(Gecko)
스파이더몽키(SpiderMonkey)
인터넷 익스플로러(Internet Explorer)
트라이덴트(Trident)
차크라(Chakra)
사파리(Safari)
웹킷(Webkit)
자바스크립트코어(JavascriptCore)
오페라(Opera)
블링크(Blink)
V8
■ Navigator 객체의 속성
console 창에서 navigator 라고 치면 Navigator 객체의 모든 정보가 한 번에 표시된다.
인터넷 익스플로러 11의 사용자 에이전트 문자열은 위와 같다. 인터넷 초창기에는 '넷스케이프 내비게이터'웹 브라우저를 많이 사용했기 때문에, 후발 주자인 인터넷 익스플로러는 넷 스케이프 사용자 에이전트 문자열과 호환되도록 넷스케이프 내비게이터에서 사용하는 Mozilla 키워드를 함께 사용했다. 인터넷 익스플로러 11에서는 트라이덴트(Trident) 엔진을 사용하기 때문에 문자열에 그 내용도 포함되어 있다.
□ 엣지
Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/42.0.2311.135 Safari/537.36 Edge/12.246
윈도우용 마이크로소프트 엣지의 사용자 에이전트 문자열은 위와 같다. 사용자 에이전트 문자열에 Chrome 과 Safari , Edge 가 모두 있기 때문에 크롬이나 사파리보다 먼저 엣지인지 체크해야 한다. 사용자 에이전트 문자열에 Edge 가 있는지 확인하면 된다.
엣지나 크롬, 사파리 브라우저에서 사용하는 웹킷(Webkit) 엔진은 오픈소스 렌더링 엔진인 KHTML에서 시작되었기 때문에 사용자 에이전트 문자열에 KHTML 엔진 이름이 함께 표시된다. 그리고 문자열에 잇는like gecko는 게코 엔진을 사용하는 예전 웹 브라우저와 호환이 된다는 의미이다.
□ 크롬
Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/81.0.4044.129 Safari/537.36
윈도우용 크롬 브라우저의 사용자 에이전트 문자열은 위와 같다. 에이전트 문자열에 Safari 도 있기 때문에 사파리보다 크롬을 먼저 체크해야 한다.
사용자 에이전트 문자열에 Chrome 문자열이 있는지 확인하면 된다.
□ 사파리, 오페라
Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_6) AppleWebKit/601.7.7 (KHTML, like Gecko) Version/9.1.2 Safari/601.7.7
맥용 사파리 브라우저의 사용자 에이전트 문자열은 위와 같다. 사용자 에이전트 문자열에 Safari 문자열이 있는지 확인하면 된다.
var agent = navigator.userAgent.toLowerCase(); // userAgent 문자열을 소문자로 변환
var name = navigator.appName;
if(name == "Internet Explorer" || agent.indexOf("triden") > -1 || agent.indexOf("edge/") > -1) { // ie 이거나 엣지
if(name == "Internet Explorer") document.write("IE 10 이하 버전입니다.");
else {
if (agent.indexOf("trident") > -1) document.write("IE 11 브라우저입니다.");
else if (agent.indexOf("edge/") > -1) document.write("MS Edge 브라우저입니다.");
}
}
else if (agent.indexOf("safari") > -1) { // 크롬이거나 사파리
if(agent.indexOf("chrome") > -1) document.write("Chrome 브라우저입니다.");
else if(agent.indexOf("safari") > -1) document.write("Safari 브라우저입니다.");
}
else if (angent.indexOf("firefox") > -1) document.write("Firefox 브라우저입니다.");
else if (agent.indexOf("opera") > -1) document.write("Opera 브라우저입니다.");
사용자 에이전트 문자열을 사용해 웹 브라우저의 종류를 확인하는 예시이다. toLowerCase( ) 함수를 사용해서 모두 소문자로 바꾼 뒤 indexOf( ) 함수를 사용해서 브라우저의 사용자 에이전트 문자열을 확인한다. indexOf( ) 는 문자열에 지정한 문자열이 있다면 그 내용의 인덱스 값을 반환하고 없으면 -1 을 반환하기 때문에 반환되는 값이 -1 보다 큰지 알아보면 된다.
History 객체
History 객체에는 브라우저에서 '뒤로', '앞으로' 또는 주소 표시줄에 입력해서 돌아다녔던 사이트 주소가 저장되어 있다. 보안 문제 때문에 브라우저에 있는 브라우저 히스토리는 읽기 전용이다.
■ History 객체의 속성과 함수
이 객체에서 사용할 수 있는 함수는 방문하면서 History 객체에 저장된 URL을 앞뒤로 이동하는 것이다.
속 성
설 명
length
현재 브라우저 창의 History목록에 있는 항목의 개수(방문한 사이트 개수)를 반환
함 수
설 명
back( )
History 목록에서 이전 페이지를 현재 화면에 불러옴
forward( )
History 목록에서 다음 페이지를 현재 화면에 불러옴
go( )
HIstory 목록에서 현재 페이지를 기준으로 상대 위치에 있는 페이지를 현재 화면에 불러옴 ex) history.go(1) 은 다음페이지를 가져오고, history.go(-1) 은 이전페이지를 불러옴
Location 객체
브라우저의 주소 표시줄과 관련된 객체이다. 현재 문서의 URL 주소 정보를 가지고 있는데, 이 정보를 편집하면 현재 브라우저 창에 열릴 사이트나 문서를 지정할 수 있다.
■ Location 객체의 속성
속 성
설 명
hash
URL 중 # 으로 시작하는 해시 부분을 나타냄
host
URL의 호스트 이름과 포트 번호를 나타냄
hostname
URL의 호스트 이름을 나타냄
href
전체 URL이다. 이 값을 변경하면 해당 주소로 이동할 수 있다.
pathname
URL 경로를 나타냄
port
URL의 포트 번호를 나타냄
protocol
http:// 나 ftp:// 같은 URL의 프로토콜을 나타냄
password
도메인 이름 앞에 username 과 password 를 함께 입력해서 접속하는 URL일 경우 password 정보를 저장
search
URL 중 ? 으로 시작하는 검색 내용 부분을 나타냄
username
도메인 이름 앞에 username 을 함께 입력해서 접속하는 사이트 URL일 경우 username 정보를 저장
■ Location 객체의 함수
함 수
설 명
assign( )
현재 문서에 새 문서 주소를 할당해 새 문서를 가져옴
reload( )
현재 문서를 다시 불러옴. 브라우저의 새로고침과 같은 역할
replace( )
현재 문서의 URL을 지우고 다른 URL의 문서로 교체 replace( ) 를 사용하면 이전버튼을 눌러도 이전 문서로 이동할 수 X
toString( )
현재 문서의 URL을 문자열로 반환
Screen 객체
주로 화면(PC 모니터나 모바일 기기의 화면 자체) 정보를 알아낼 때 많이 사용하는 객체이다.
■ Screen 객체의 속성
속 성
설 명
availHeight
화면에서 윈도우의 작업 표시줄이나 맥의 메뉴/독 같은 UI 영역을 제외한 부분의 높이
availWidth
UI 영역을 제외한 부분의 너비
colorDepth
화면상에서 픽셀을 렌더링할 때 사용하는 색상 수
height
UI 영역을 포함한 높이
orientation
화면의 현재 방향(기본값은 가로방향)
pixcelDepth
화면상에서 픽셀을 렌더링할 때 사용하는 비트 수
width
UI 영역을 포함한 화면의 너비
■ Screen 객체의 함수
아래 두 함수는 풀 스크린 상태일 때나 방향 전환이 가능한 앱에서 사용할 수 있다.
함 수
설 명
lockOrientation( )
화면 방향을 잠금
unlockOrientation( )
화면 방향 잠금 해제
■ Screen 객체와 Window 객체 속성의 차이점
Window 객체의 innerWidth / innerHeight 나 outerWidth / outerHeight 속성은 웹 브라우저 창의 너비나 높이를 측정하고, Screen 객체의 availWidth / availHeight 나 width / height 속성은 화면 자체의 너비나 높이를 측정한다. 그래서 웹 브라우저 창의 크기를 늘리거나 줄인 후 새로고침을 누르면 Window 객체의 속성 값은 바뀌지만 Screen 객체의 속성 값은 바뀌지 않는다.
DOM에서 요소에 접근하는 것과 같은 방식이다. querySelector( ) 함수나 querySelectorAll( ) 함수를 이용해서 특정 id 값이나 class 값을 가진 요소에 접근할 수 있다. id 값을 사용할 때는 폼 요소 하나에만 접근하고, class 값을 사용할 때는 여러 요소를 가져와 배열 형태로 저장한다.
value 속성을 사용하면 텍스트 필드에 있는 값을 가져올 수 있다.
2. name 값을 사용해 폼 요소에 접근
<form name="ship">
...
<input type="text" class="input-box" id="shippingName" name="shippingName">
...
</form>
<script>
document.ship.shippingName; //폼 요소를 포함하고 있는 폼 요소부터 계층에 따라 하나씩 지정
document.forms["ship"].elements["shippingName"]; //이렇게 해도 결과는 같다.
</script>
자바스크립트에서 폼 요소를 구별하고 접근할 수 있도록 HTML 초기부터 사용하던 방법이다. 이 방법을 사용하려면 <form> 태그에 name 속성이 지정되어 있어야 하고, <form> 태그 안에 포함된 폼 요소에도 name 속성이 있어야 한다. 폼 요소에 접근할 때는 form 의 name 값부터 폼 요소의 name 값까지 계층을 따라 하나씩 지정해준다.
마찬가지로 .value 를 하면 텍스트 필드에 있는 값을 가져올 수 있다.
3. 폼 배열을 이용해서 접근
document 의 속성 중 forms 속성은 문서 안에 있는 <form> 태그를 모두 가져와 배열 형태( HTMLCollection )로 반환한다. 폼 요소에 id 나 class 속성도 없고 name 속성도 없을 때 사용한다. 폼 배열을 사용하는 방법은 웹 문서에 <form> 태그가 몇 개나 사용되었는지 알고 있어야 하고, <form> 태그 안에 폼 요소가 많을 경우 원하는 요소에 접근하기 쉽지 않기 때문에 자주 사용되지는 않는다.
document.forms[0].elements[0]
document.forms[0].elements[0].value //value를 사용하면 값을 가져올 수 있다.
<form> 태그 안에 포함된 요소에 접근하려면 elements 속성을 사용한다.
(해당 폼 안에 있는 폼 요소를 모두 가져오는 속성)
forms[인덱스] 안에 있는 요소를 모두 가져오면 HTMLFormControlsCollection 배열 형태로 저장된다.
안을 살펴보면 어떤 요소가 저장되었는지 확인하는 것도 가능하다.
입력값 검증
보통 정규 표현식을 사용해서 입력값을 검증한다. 태그 자체에서 폼을 검증하는 방법도 있다.
■ 태그 자체에서 폼 검증
자바스크립트 대신 <input> 태그의 type 속성 값을 사용해서 필드 값을 체크할 수도 있다. 오류 메시지는 브라우저에서 처리하기 때문에 브라우저마다 오류 내용이 다르다.
[폼 검증과 관련된 <input> 태그의 type 속성]
유 형
설 명
<input type="email">
이메일 주소 필드. 이메일 주소 형식에 맞지 않으면 오류 메시지를 표시
<input type="tel">
전화번호 필드 전화번호 숫자가 아닌 내용을 입력하면 오류 메시지를 표시
<input type="url">
사이트 주소 필드 http: 로 시작하지 않으면 오류 메시지를 표시
[폼 검증과 관련된 <input> 태그의 속성]
속 성
설 명
autocomplete
자동 완성 기능을 켜고 끄는 속성
autofocus
해당 필드에 마우스 커서를 자동으로 표시
placeholder
필드 안에 힌트가 표시되어 사용자에게 어떤 내용을 입력해야 하는지 알려줌
required
필수 입력 항목으로 지정. 필드를 작성하지 않으면 오류 메시지를 표시하며 다음 단계로 넘어갈 수 X
[참고] select( )와 focus( )
텍스트 필드를 검증해서 오류가 발생했을 때 사용자가 입력한 값을 처리할 때 아래 두 함수를 사용할 수 있다.
select( ) : 자바 내장 함수로 텍스트 필드에 입력한 내용을 선택 (사용자가 기존에 입력한 값을 선택)
focus( ) : 기존에 입력한 값이 지워진 자리에 새로운 값을 입력하도록 텍스트 필드에 커서를 가져다 놓음
다양한 폼 요소 다루기
선택 목록(팝업 메뉴)
라디오 버튼
체크 상자
1. 선택 목록(팝업 메뉴)
■ 선택 목록(<select>) 및 옵션 항목에 접근
선택 목록 : <option> 태그를 사용해 여러 항목을 한꺼번에 지정한 뒤 목록을 펼쳐 원하는 항목을 선택할 수 있는 요소
위에 나온 폼 접근 방식으로 선택 목록에도 접근할 수 있다.
선택 목록의 항목은 여러 개인 경우가 많기 때문에 자바스크립트에서 선택 목록에 접근하면 선택 목록에 있는 옵션 항목은 배열 형태( HTMLOptionsCollection )로 저장된다.(괄호 안의 숫자는 option의 개수)
옵션 항목에 접근하는 경우 options 속성을 사용하면 된다.
length 속성에는 옵션 항목의 개수가 저장되어 있다.
selectedIndex 에는 여러 옵션 중 사용자가 선택한 옵션의 인덱스 값이 저장된다.(아무것도 선택하지 않으면 기본값 0)
options[인덱스 값] 하면 해당 순서의 옵션 항목에 접근할 수 있다.
innerText 을 사용하면 해당 옵션이 화면에 표시하는 내용에 접근할 수 있다.
value 를 사용하면 어떤 값을 서버로 넘겨주는지 확인할 수 있다.
■ 선택 목록에서 사용자가 선택한 옵션 항목 찾아내기
자바스크립트로 선택 목록에 접근하면 배열 형태가 반환되는데, 배열 안에는 selectedIndex 속성이 있다.
라디오 버튼은 같은 같은 name 값을 가진 요소가 여러 개이기 때문에 RadioNodeList 라는 이름의 노드 리스트 형태로 저장된다.
document.querySelectorAll('input[name="subject"]')
document.querySelectorAll('input[name="subject"]')[0] //인덱스를 사용하는 것도 가능
//value 속성을 사용하면 라디오 버튼을 선택했을 때 어떤 값을 서버에 넘겨주는지 확인할 수 있다.
document.querySelectorAll('input[name="subject"]')[0].value
//checked 속성을 사용하면 라디오 버튼이 선택되었는지 확인할 수 있다.
document.querySelectorAll('input[name="subject"]')[1].checked
name 값 외에도 querySelector( ) , querySelectorAll( ) 을 이용해서 라디오 버튼에 접근할 수 있다.
value 속성 : 라디오 버튼을 선택했을 때 서버로 넘겨주는 값 (아무것도 선택하지 않으면 빈 값)
checked 속성 : 기본값은 false (해당 항목을 선택하면 값이 true로 바뀐다)
//name값이 각각 다른 경우
document.querySelectorAll('input[name="mailing"]')
//name값이 전부 같은 경우
document.querySelectorAll('input[name="mailing"]')
document.querySelectorAll('input[name="mailing"]')[0] //인덱스를 넣어서 특정 checkbox에 접근할 수 있다.
//value 속성을 사용하면 체크했을 때 어떤 값을 서버에 넘겨주는지 확인할 수 있다.
document.querySelectorAll('input[name="mailing"]')[0].value
//checked 속성을 사용하면 해당 체크박스가 체크되었는지 확인할 수 있다.
document.querySelectorAll('input[name="mailing"]')[0].checked
name 값 외에도 querySelector( ) , querySelectorAll( ) 을 이용해서 체크박스에 접근할 수 있다.