본문 바로가기
Programming/JavaScript

[CodeAcademy] object, this, getter, setter

// Objects ~ Dict in Python  : key값은 식별자(1단어, 단순 숫자 등)인 경우 따옴표 생략 가능
let fasterShip = {
  'Fuel Type' : 'Turbo Fuel',
  color : 'silver'    
};
let spaceship1 = {
  homePlanet: 'Earth',
  color: 'silver',
  'Fuel Type': 'Turbo Fuel',
  numCrew: 5,
  flightPath: ['Venus', 'Mars', 'Saturn']
};
let crewCount = spaceship1.numCrew; // 따옴표 없는 key의 경우, fasterShip.color; 형식으로 접근 가능
let planetArray = spaceship1.flightPath;
console.log(crewCount, planetArray);

let propName =  'Active Mission';
let isActive = spaceship1[propName];
console.log(isActive);

let spaceship2 = {
  'Fuel Type' : 'Turbo Fuel',
  homePlanet : 'Earth',
  color: 'silver',
  'Secret Mission' : 'Discover life outside of Earth.'
};
spaceship2.color = 'glorious gold'; // 키값 value 변경
spaceship2.numEngines = 5; // key - value 추가
delete spaceship2['Secret Mission']; // 특정된 key 지우기
console.log(spaceship2);

// method: 큰 클래스에 정의된 함수 ~ 여기서는 obejct의 key는 함수이름, value는 그 출력물
let retreatMessage = 'We no longer wish to conquer your planet. It is full of dogs, which we do not care for.';
const alienShip = { 
  retreat() {
    console.log(retreatMessage);
  },
  takeOff() {
    console.log('Spim... Borp... Glix... Blastoff!');
  }
};
alienShip.retreat();
alienShip.takeOff();  // 클래스에 정의된 메소드(함수) 호출처럼 함수내에 key를 매소드 호출형식으로 동작


let spaceship = {
  passengers: null,
  telescope: {
    yearBuilt: 2018,
    model: "91031-XLT",
    focalLength: 2032 
  },
  crew: {
    captain: { 
      name: 'Sandra', 
      degree: 'Computer Engineering', 
      encourageTeam() { console.log('We got this!') },
     'favorite foods': ['cookies', 'cakes', 'candy', 'spinach'] }
  },
  engine: {
    model: "Nimbus2000"
  },
  nanoelectronics: {
    computer: {
      terabytes: 100,
      monitors: "HD"
    },
    'back-up': {
      battery: "Lithium",
      terabytes: 50
    }
  }
}; 
let capFave = spaceship.crew.captain['favorite foods'][0];  // dot과 []를 이용해서 경로에 맞게 호출
spaceship.passengers = [{number: 5}];
let firstPassenger = spaceship.passengers[0];

let spaceship3 = {  // 함수를 통해 입력될 object 메모리 주소(참조값)을 추적하여 내용 수정하기
  'Fuel Type' : 'Turbo Fuel',
  homePlanet : 'Earth'
};
const greenEnergy = object => {
  object['Fuel Type'] = 'avocado oil';
};
const remotelyDisable = object => {
  object.disabled = true;
};
greenEnergy(spaceship3);
remotelyDisable(spaceship3); 
console.log(spaceship3)

// 이 경우 spaceship2 내용 안바뀜
let spaceship2 = {
  homePlanet : 'Earth',
  color : 'red'
};
let tryReassignment = obj => {
  obj = {
    identified : false, 
    'transport type' : 'flying'
  }
  console.log(obj) 
};
tryReassignment(spaceship2);
console.log(spaceship2); // 내용 그대로임 
/* 

이유: 함수에 입력되는 것은 변수(객체) 자체 입력이 아닌 변수와 같은 메모리 주소(참조값)만 입력됨 -> 원본 유지 
 -> 함수 내부 obj만 새로운 값으로 바뀔 뿐

 */


let spaceship = {
    crew: {
    captain: { 
        name: 'Lily', 
        degree: 'Computer Engineering', 
        cheerTeam() { console.log('You got this!') } 
        },
    'chief officer': { 
        name: 'Dan', 
        degree: 'Aerospace Engineering', 
        agree() { console.log('I agree, captain!') } 
        },
    medic: { 
        name: 'Clementine', 
        degree: 'Physics', 
        announce() { console.log(`Jets on!`) } },
    translator: {
        name: 'Shauna', 
        degree: 'Conservation Science', 
        powerFuel() { console.log('The tank is full!') } 
        }
    }
}; 

for (let crewMember in spaceship.crew) {
  console.log(`${crewMember}: ${spaceship.crew[crewMember].name}`);
}; // string 내부에 연산을 위해 ``(따옴표아님) 사이에 ${} 로 동작

for (let crewMember in spaceship.crew) {
  console.log(`${spaceship.crew[crewMember].name}: ${spaceship.crew[crewMember].degree}`)
}; // 주소를 그대로 찾아가면됨. 단 creMember.name 은 안됨(crewMember는 순회 돌 때에 string 하나일 뿐임)
/*
주소가 너무 길면 아래처럼 자주 사용되는 공통 부분을 변수로 지정하는 방법이 있다.

for (let role in spaceship.crew) {
  const member = spaceship.crew[role];
  console.log(`${role}: ${member.name}`);
}

for (const [key, value]) of Object.entries()로 key와 value를 한번에 추출할 수 있다.

for (const [role, member] of Object.entries(spaceship.crew)) {
  console.log(`${role}: ${member.name}`);
}
for (const [, member] of Object.entries(spaceship.crew)) {
  console.log(`${member.name}: ${member.degree}`);
}

sub dict의 key를 한 번에 호출하려면 하려면 아래와 같이 작성
for (const [role, { name, degree }] of Object.entries(spaceship.crew)) {
  console.log(`${role}: ${name}`);
  console.log(`${name}: ${degree}`);
}

 */

const goat = {
  dietType: 'herbivore',
  makeSound() {
    console.log('baaa');
  },
  diet() {
    console.log(dietType);
  }
};
goat.diet(); 
/* Output will be "ReferenceError: dietType is not defined"
-> dietType을 diet()내부 그리고 goat 밖에서 찾지 못해서 생긴 오류
goat 내부 안의 dietType은 object property로 굳이 참조하지 않음
 -> this.dietType해야 가능
*/

const robot = {
  model: '1E78V2',
  energyLevel: 100,
  provideInfo() {
    return `I am ${this.model} and my current energy level is ${this.energyLevel}.`
  },
};
console.log(robot.provideInfo());

// arrow function의 this는 global scope를 참조하므로 객체 property를 찾지 않기 때문에 undefined 출력됨
const goat1 = {
  dietType: 'herbivore',
  makeSound() {
    console.log('baaa');
  },
  diet: () => {
    console.log(this.dietType);
  }
};

goat1.diet(); // Prints undefined
 // -> 따라서 this 사용시 arrow function 대신 () {} 로 바꿔서 쓰는게 작동 잘됨
// '_이름' 형태로 지은 것: privacy(값 변경 가능하지만 가능한 값을 바꾸지말라는 의미)
const robot3 = {
  _energyLevel: 100,
  recharge(){
    this._energyLevel += 30;
    console.log(`Recharged! Energy is currently at ${this._energyLevel}%.`)
  }
};
robot3._energyLevel = 'high';
robot3.recharge();

// getter: get 이름() {} 로 구현하고 this.로 property 받아서 구현. property를 get하는 기능
const robotget = {
  _model: '1E78V2',
  _energyLevel: 100,
  get energyLevel() {
    if (typeof this._energyLevel === 'number') {
    return `My current energy level is ${this._energyLevel}`;
    } else {
      return 'System malfunction: cannot retrieve energy level';
    }
  }
};
console.log(robotget.energyLevel); // get name은 일반 속성처럼 호출 가능 (주의점: getter과 setter 이름 일치하면 loop 빠짐)

// setter: property 값 재설정

const robotset = {
  _model: '1E78V2',
  _energyLevel: 100,
  _numOfSensors: 15,
  get numOfSensors(){
    if(typeof this._numOfSensors === 'number'){
      return this._numOfSensors;
    } else {
      return 'Sensors are currently down.'
    }
  },
  set numOfSensors(num) {
    if (typeof num == 'number' && num >= 0 ) {
      this._numOfSensors = num;
    } else {
      console.log('Pass in a number that is greater than or equal to 0');
    }
  }
};
robotset.numOfSensors = 100;
console.log(robotset.numOfSensors);
728x90
반응형