JavaScript-객체
객체란?
이름이 있는 정리상자
- 문법
var coworkers = {}; // -> 객체는 중괄호 var coworkers = []; // -> 배열은 대괄호 // 지금은 둘 다 비어있는 상태
<script type="text/javascript"> // 객체상수로부터 객체 생성 var coworkers = { "programmer" : "myunggwan", "designer" : "yoom" }; document.write("programmer : " + coworkers.programmer + "<br>"); document.write("designer : " + coworkers.designer+ "<br>"); coworkers.bookkeeper = "jun"; document.write("bookkeeper : " + coworkers.bookkeeper+ "<br>"); coworkers["data scientist"] = "wook"; document.write("data scientist : " + coworkers["data scientist"]); </script>
※ 자바와 마찬가지로 객체의 필드나 메소드에 접근하기 위해서는 .을 사용한다.
- 배열이용 - 향상된 for문
for(var target in coworkers) { document.write(target + " : " +coworkers[target] +"<br>"); }
이런 식으로 for문에서 순서대로 객체의 정보들을 순환해서 찾아갈 때에는 배열에서 쓰던 대괄호를 이용한다.
index: 배열 안의 데이터는 순서대로 배치되어 있음. key: 객체에 속한 데이터는 순서대로 정리되어 있지 않음. → 순서는 그냥 선언된 순서
객체상수로 생성한 객체에선 안의 내용물을 구분할 때 ;가 아니라 ,로 구분한다.
- 주의해야할 점 - 계속 오류떴는데 해결
// 객체상수로부터 객체 생성 var Body = { var setColor : function (color){ document.querySelector('body').style.color = color; }, var setBackgroundColor : function (color){ document.querySelector('body').style.backgroundColor = color; } }; // 잘못된 코딩
- 이런 식으로 코딩하면 절대 결과가 안나옴.
- 객체생성할 때 내부 프로퍼티 선언은 var을 앞에 붙히면 안된다.
- 그냥 바로 변수이름 때려박아야함.
var Body = { setColor : function (color){ document.querySelector('body').style.color = color; }, setBackgroundColor : function (color){ document.querySelector('body').style.backgroundColor = color; } }; // 올바른 예
※ 자바스크립트에선 함수가 객체 내에 내장되어있으면 그걸 메소드라고 부름.
객체의 종류
- 내장객체
- 말그대로 자바스크립트 내에 잘 정의되어있는 객체
- 예를 들면 Date, Array, String, document
- 따로 생성자함수를 정의하지 않고도 사용이 가능하다.
- 사용자 정의 객체
- 사용자 정의 객체를 생성하는 데에도 2가지 방법으로 나뉜다.
- 객체 상수로부터 직접 생성하기 (싱글톤) → 위에서 계속 했던 방식
// 객체상수로부터 객체 생성 var myCar = { model : "bmw", speed : 60, color : "red", brake : function () { this.speed -=10; }, accel : function () { this.speed += 10; } };
- 이렇게 하면 객체의 이름은 myCar이고 바로 myCar.color 또는 myCar.brake() 과 같은 구성요소를 사용할 수 있음. - 이 방식은 간단하긴 하지만 객체를 하나만 생성한 거고 다른 종류의 차를 만들어내려면 코드를 반복해야한다. 이렇게 정의된 객체를 **싱글톤**이라고 부르고 객체가 하나만 생성된 것을 의미한다.
- 객체 상수로부터 직접 생성하기 (싱글톤) → 위에서 계속 했던 방식
-
생성자 함수를 이용한 객체 생성 (진정한 사용자 정의 객체)
- 자바와의 차이점
- 자바에서는 클래스가 있고 클래스를 정의 후 그 클래스를 설계도 삼아 객체를 찍어내는 형식이다.
- 하지만 자바스크립트는 클래스라는 개념이 없으며 모든것이 객체이며 생성자 함수가 클래스의 역할을 흉내낸다.
//생성자함수 function Car (model, speed, color) { this.model = model; this.speed = speed; this.color = color; this.brake = function() { this.speed -=10; } this.accel = function() { this.speed += 10; } }
- 이렇게 생성자함수를 정의해놓으면 이제 new 연산자를 이용해 객체를 찍어내어 변수에 저장할 수도 있다.
var myCar = new Car("bmw", 60, "yellow"); var yourCar = new Car("kia", 40, "black");
- 사용방식은 똑같이 myCar.color 또는 yourCar.brake() 이런 식으로 쓴다.
- 이 상태에서 새로운 멤버변수나 멤버메소드를 추가하고 싶으면 아래와 같이 따로 선언을 하면 된다.
myCar.turbo = "100"; yourCar.showModel = function() { alert("해당 자동차의 모델은 " + this.model + "입니다."); };
- 사용자 정의 객체를 생성하는 데에도 2가지 방법으로 나뉜다.
프로토타입
- 객체들은 자신만의 데이터를 가져야하는 건 당연히 맞는 말이지만 같은 계산을 하는 알고리즘을 가진 메소드를 각 객체마다 따로 따로 가지고 있는건 명백한 메모리 낭비이다.
- 자바에선 이걸 클래스에서 해소해주고 있는데 자바스크립트에는 클래스가 없다.
- 자바스크립트에서 클래스 대신 역할 해주는 것이 바로 프로토타입!!
- 이 프로토타입을 이용해서 여러 객체가 공유하는 메소드를 정의할 수 있다.
- 예시코드
//Point 객체 생성자 함수 function Point (x, y) { this.x = x; this.y = y; this.getDistance = function () { return Math.sqrt(this.x * this.x + this.y * this.y); } }
→ 이렇게 객체를 생성하는 생성자함수를 정의해 놓으면 멤버변수를 다양하게 받아 아래와 같이 객체를 변수에 저장할 수 있다.
var p1 = new Point(4,5); p1.getDistance(); var p2 = new Point(74,8); p2.getDistance();
→ p1과 p2 참조변수엔 서로 다른 4,5 74,8 이라는 멤버변수가 있지만 같은 getDistance라는 메소드를 공유한다. 이런 메모리 낭비를 막기위해선 아래와 같이 모든 객체에 숨겨져있는 프로토타입객체를 사용한다.
function Point (x, y) { this.x = x; this.y = y; }; Point.prototype.getDistance = function () { return Math.sqrt(this.x * this.x + this.y * this.y); };
→ 이렇게 하면 한 번의 선언으로 모든 Point객체가 getDistance메소드를 공유할 수 있다. → x랑 y는 각 객체 내부에서 갖는 거라 인스턴스 속성이지만 getDistance는 모든 객체가 공유하기에 클래스속성이라고 부른다. → 사용방법은 이전과 똑같다.
var p1 = new Point(4,5); p1.getDistance(); var p2 = new Point(74,8); p2.getDistance();
프로토타입-체인
참조 프로세스
- 객체 안에 속성이나 메소드가 정의되어 있는지 찾는다.
- 없으면 해당 객체의 prototype객체에 정의되어있는지 찾는다.
- 찾을 떄까지 prototype 체인을 따라서 올라간다.. (최상위는 object)
→ Object객체에는 toString()이라는 메소드가 있다. 따라서 모든 객체들은 프로토타입체인을 따라서 toString()메소드를 사용할 수 있다. → 약간 자바의 상속개념과 비슷하다고 생각하면 편함.
내장객체
- Date 객체
var today = new Date(); // 현재의 날짜와 시간이 저장됨
- Number 객체
var num = new Number(7);
- String 객체
- 자바와 거의 비슷함! 개꿀
- length, split(), concat(), replace(), indexOf(), toUpperCase() 등등 똑같음 (매개변수 형태도 같음)
- 자바와 마찬가지로 두 가지 종류의 객체로 나뉘어져있음
- 문자열 리터럴
- 문자열 객체
var strLiteral = "문자열 리터럴"; var strObject = new String("문자열 객체"); strLiteral.concat("456"); // 리터럴도 객체의 메소드를 자유롭게 쓸 수 있음.
- Math 객체
- 자바와 비슷하게 쓰임
- Math.PI와 같은 속성이나 Math.round(), Math.sqrt(), Math.abs()같은 메소드도 쓸 수 있음.
Array객체
- 선언방식
var arr = new Array(); arr[0] = "orange"; arr[1] = "banana"; var arr = new Array("orange", "banana"); var arr = ["orange", "banana"];
→ 이렇게 총 3가지 방식이 있다.
- 특이한 점 2가지
- 배열크기가 자동조절 ```javascript var arr = new Array(); arr[0] = “orange”; arr[99] = “banana”; // 이렇게 하면 배열크기가 자동으로 100이 됨.
- 배열 안에서 여러가지 자료형으로 저장가능 var arr = new Array(); arr[0] = “orange”; arr[1] = new Date(); arr[2] = 123; ```
- Array 객체의 속성과 메소드
- 자바와 굉장히 닮아 있다.
- length, concat(), indexOf(), push(), pop(), shift(), join()과 같은 속성과 메소드가 쓰임.
- 2차원 배열도 가능
var x = [4,5,8,45,2,9]; var y = [87,12,6,35,49]; var z = [x, y]
예외처리
var answer = 45; function guess () { try { var s = parseInt(document.getElementId("insert").value); if(s<answer) throw "너무 작아용"; if(s>answer) throw "너무 커용"; if (s==="") throw "입력없음"; } catch (error) { var al = "해당 오류는 : " + error; document.getElementId("input").value = al; } }
댓글남기기