TIL/JavaScript

[JavaScript] 객체

yndev 2022. 2. 20. 01:28

객체

- 다른 자료형은 오직 하나의 데이터만 담을 수 있는 원시형(primitive type)이지만 객체는 다양한 데이터를 담을 수 있다.

 

객체 선언 및 호출

- 객체는 프로퍼티(키-값 쌍)를 저장하며 키 값을 사용하여 속성을 식별한다.
- 키는 문자열이며 속성에는 모든 자료형이 올 수 있다.
- 객체 생성자 또는 중괄호 {} 를 사용하여 객체를 생성한다.

        function test1() {
            //객체 생성자 호출
            let obj = new Object();
            //객체 리터럴 선언
            let obj2 = {};

            let product = {
                //키-값 쌍으로 구성된 프로퍼티
                pName : 'Dry Mango',
                origin : 'Phillipines',
                price : 10000,
                ingredient : ['mango', 'sugar']
            };

            console.log('객체명.속성명으로 접근');
            console.log(product.pName);
            console.log(product.origin);
            console.log(product.price);
            console.log(product.ingredient);
            console.log(product.ingredient[0]);
            console.log(product.ingredient[1]);

객체명['속성명'] 입력할 때 single quotation이 잘 손에 안 붙는다.. 위의 표현식이 나에겐 더 맞음

            console.log("객체명['속성명']으로 접근");
            console.log(product['pName']);
            console.log(product['origin']);
            console.log(product['price']);
            console.log(product['ingredient']);
            console.log(product['ingredient'][0]);
            console.log(product['ingredient'][1]);

 

객체의 키 식별자 테스트

- 객체의 키는 모든 문자열을 사용할 수 있다.
- 단, 식별자로 사용할 수 없는 단어를 키로 사용하거나 변수를 키로 사용하는 경우 무조건 대괄호를 사용해야 객체의 요소에 접근할 수 있다.

 

- 객체명.속성명 접근 불가

            function test2(){
                let objTest = {
                    'hello world' : 'Hello World!!',
                    '!@#$%^&*()' : 1234567890,
                    test : true
                };

                //변수에 담긴 key값
                let key = "test";

                console.log("=== objTest ===");
                console.log(objTest);

                console.log("객체명.속성명 접근 불가");
                //console.log(objTest.'hello world');
                // console.log(objTest.'!@#$%^&*()');
                console.log(objTest.key);
                console.log(objTest.test);
            }
            test2();

객체명.속성명 접근 불가 부분에서 console.log(objTest.test); 는 true로 잘 출력됐다.

- 객체명['속성명']으로 접근 가능

                console.log("객체명['속성명']으로 접근 가능");
                console.log(objTest['hello world']);
                console.log(objTest['!@#$%^&*()']);
                console.log(objTest[key]);

 

상수 객체는 수정 가능

- 상수 배열/객체의 속성은 변경 가능하나 상수 배열/객체를 다시 할당할 수는 없다.

            function test3() {
                const student = {name : '김땡땡', age : 20};
                console.log(student);

 

- 해당 객체에서 속성 값 변경은 가능하다

- 새로운 객체 재할당은 불가능하다

                student = {name : '김땡땡', age : 40};


객체의 속성 추가와 제거

- 처음으로 객체 생성한 이후 속성을 추가하거나 제거하는 것을 동적으로 속성을 추가한다 혹은 제거한다 라고 한다.

 

- 빈 객체 생성

                let student = {};
                console.log(student);

- 객체에 속성 추가

                student.name = '주땡땡';
                student.hobby = '게임';
                student.strength = '프로그래밍';
                student.dream = '개발자';

                console.log(student);

- 객체 속성 제거(취미인 게임 제거)

                delete(student.hobby);
                console.log(student);

 

함수 활용한 객체 생성

            function makeStudent(name, score){
                let student = {
                    name : name,
                    score : score
                };
                return student;
            }

- 위 코드 단축 프로퍼티

            function makeStudent(name, score){
                return{
                    name,
                    score
                };
            }

 

in 키워드

- 객체 내부에 해당 속성이 있는지 확인하는 키워드

            function test5(){
                let student = {
                    name : '주땡땡',
                    kor : 100,
                    eng : 80,
                    math : 90,
                    test : undefined
                };

                console.log('name' in student);
                console.log('kor' in student);
                console.log('eng' in student);
                console.log('math' in student);
                console.log('sum' in student);
                console.log('test' in student);

- 값이 undefined인 속성인 in 연산자로 확인하는 것이 정확한다.

(값이 없는 sum과 test와 동일한 undefined 출력)

                console.log(student.name);
                console.log(student.sum);
                console.log(student.test);

 

객체와 반복문

- 객체의 속성을 살펴볼 때에는 단순 for문으로는 사용 불가능하고 for in문을 사용해야 한다.

            function test6() {
                let game = {
                    title : 'DIABLO 3',
                    price : 35000,
                    language : '한국어지원',
                    supportOS : 'windows 32/64',
                    service : true
                };

                console.log(game);
                console.log("=== 반복문 동작 ===");

                for(let key in game){
                    console.log(key + " : " + game[key]);
                }
            }
            test6();

 

객체의 메소드 속성

- 객체의 속성에 저장 된 함수를 메소드라고 하며 객체명.메소드() 와 같은 형식으로 사용된다.
- 메소드는 this로 객체를 참조한다.

            function test7(){
                let name = "뽀삐";
                let dog = {name : "쪼꼬"};

//함수 표현식으로 함수를 만들고 객체 속성 dog.eat에 할당
//=> 메소드로 등록한다
                dog.eat = function(food){
                    console.log(name + "가 " + food + "를 먹고 있네요.");
                    //객체 내에서 자신의 속성을 호출할 때는 반드시 this사용
                    console.log(this.name + "가 " + food + "를 먹고 있네요.");
                };
                //메소드 호출
                dog.eat("고구마");
                //선언된 함수 메소드로 등록
                dog.walk = walk;
		//메소드 호출
                dog.walk("테헤란로");

            }
            function walk (place) {
                console.log(this.name + "가 " +  place + "를 산책하고 있네요.");
            }

            test7();

 

                let human = {
                    name : '주땡땡',

                    eat(food){
                        console.log(this.name + "이 " + food + "를 먹고 있어요.");
                        //this를 사용하지 않고 외부 변수를 참조해서 객체에 접근
                        //가능하기는 하지만 변수명이 변경되는 상황 등이 있을 수 있으므로
                        //항상 this로 참조하자
                        //console.log(human.name + "이 " + food + "를 먹고 있어요.");
                    }
                }

                human.eat("짬뽕");

                //외부 변수 참조시 발생할 수 있는 문제
                let person = human;
                human = null;
                person.eat("샐러드");

 

생성자 함수

- 유사한 객체를 여러 개 만들어야 할 때 생성자 함수를 사용한다.
- 생성자 함수와 일반 함수는 기술적으로 다르지 않지만 함수 이름의 첫 글자는 대문자로 시작하고 new 연산자를 붙여 실행한다는 규칙이 있다.

            function test8() {
                // 생성자 함수 호출하여 객체 생성
                let student1 = new Student("주땡땡", 100, 90, 80, 70, 60);
                console.log(student1);
                console.log("student 점수 합계 : " + student1.getSum());
                console.log("student 점수 평균 : " + student1.getAvg());

                let student2 = new Student(prompt("이름입력"),
                                           Number(prompt('java 점수 입력')),
                                           Number(prompt('oracle 점수 입력')),
                                           Number(prompt('html 점수 입력')),
                                           Number(prompt('css 점수 입력')),
                                           Number(prompt('javascript 점수 입력')));

                console.log(student2);
                console.log("student2 점수 합계 : " + student2.getSum());
                console.log("student2 점수 평균 : " + student2.getAvg());

                //배열 선언
                let students = [];

                //배열에 객체 담기
                students.push(student1, student2);

                //객체 배열 출력
                console.log(students);
            }
            test8();

 

find와 findIndex

- 객체 배열을 대상으로 특정 조건이 부합하는 객체를 배열 내에서 검색할 수 있다.
- 배열 요소를 대상으로 함수가 순차적으로 호출 된다.

- let 변수 = 배열.find/findIndex(function(item, index, array) {
             // true가 반환 되면 반복이 멈추고 해당 요소를 반환/해당 요소의 인덱스 반환             
             // 조건에 해당하는 요소가 없으면 undefined를 반환});

 

            function test9() {
                let students = [ new Student("수지", 100, 90, 95, 85, 80),
                                 new Student("제니", 70, 80, 90, 75, 60),
                                 new Student("유아", 80, 65, 55, 90, 90)];
                //제니라는 이름을 가진 학생 찾기
                let jennie = students.find(item => item.name == '제니');
                console.log(jennie);

                //영미라는 이름을 가진 학생 찾기
                let youngmi = students.find(item => item.name == '영미');
                console.log(youngmi);


            }
            test9();

값이 없으면 undefined 출력

 

                //java점수가 90점 이상인 학생의 인덱스 찾기
                let java = students.findIndex(item => item.java >= 90);
                console.log(java);

                //oracle점수가 60점 미만인 학생의 인덱스 찾기
                let oracle = students.findIndex(item => item.oracle < 60);
                console.log(oracle);

java점수가 90점 넘는 학생이 0번째 인덱스 / oracle점수가 60점 미만 학생이 없으니 -1 출력

                //평균 점수가 70점대 이상인 학생 인덱스 찾기
                let avg70 = students.findIndex(item => item.getAvg() >= 70 && item.getAvg() < 80);
                console.log(avg70);

1번, 2번 인덱스가 조건에 맞는데 1번인덱스만 출력이 됐다.

여러 값을 구할 때는 find나 findIndex로는 맞지 않다. 밑에서 filter로 출력해보자.

 

filter

- find/findIndex는 처음 true가 반환 된 하나의 요소만 반환 가능하므로 조건을 충족시키는 요소가 여러 개라면 filter 메소드를 사용한다.
- 문법은 유사하지만 조건에 맞는 요소 전체를 담은 배열을 반환한다.

                let avg70 = students.filter(item => item.getAvg() >= 70 && item.getAvg() < 80);
                console.log(avg70);