TIL032 JavaScript Wrap-up

헷갈리는 개념들을 한번씩 되짚어보자! 😣🙈😎

1. Introduction to JavaScript

  • JS는 웹페이지와 상호작용하도록 만들어진 언어.
  • 브라우저에서 사용자의 행동을 처리하고, 데이터도 저장하고, 네트워크 응답과 요청을 처리한다.

2. Function Basic

1) return

  • 모든 함수는 값을 반환한다.(return이 명시 되어 있지 않은 경우 return undefined가 생략되어 있는 것)

2) 매개변수(parameter)와 인자(argument)

function getName(name) {
  return name + '님';
}
  • 매개변수: 외부로부터 들어오는 값을 담아 함수 내부에서 사용하도록 하는 변수의 역할, 위 함수에서 name이 해당한다. 함수에서 전달되는 인자들을 담아두는 곳.
let result1 = getName('개발자'); // '개발자님' 출력
let result3 = getName('프론트엔드 개발자'); // '프론트엔드 개발자님' 출력
let result4 = getName('백엔드 개발자'); // '백엔드 개발자님' 출력
  • 인자: 위 코드에서 '개발자', '프론트엔드 개발자', '백엔드 개발자'와 같은 값이 인자, 즉 함수 호출 시에 매개변수 자리에 들어가는 구체적인 값을 뜻한다.

3. Math Expressions

let num = 1;
let newNum = num++;
console.log(num); //2
console.log(newNum); //1
  • 결과값이 반대로 나와야할 것 같지만, 그렇지 않다.
  • 그 이유는 아래 사진과 같다.
  • 결과값이 반대로 나오려면 아래와 같이 코드를 입력해야한다.
let newNum = ++num;

4. String

1) String 기초

console.log("2 더하기 2는 " + 2 + 2); //2 더하기 2는 22
  • 위와 같이 코드를 실행하면 "2 더하기 2는 4"가 아닌 "2 더하기 2는 22"가 출력된다. 그 이유는 프로그래밍은 왼쪽부터 순서대로 실행되기 때문이다.
  • 위와 같이 서로 다른 type인 string+number를 할때는 항상 주의해야한다!
  • String과 Number를 더하면 항상 String으로 변환된다.
  • 그래서 우리가 원하는 값으로 변환하려면 아래와 같이 코드를 입력해야한다.
console.log("2 더하기 2는 " +  (2 + 2)); //2 더하기 2는 4

2) indexOf: 문자열 찾기

  • indexOf 메소드는 문자열에 특정 문자열이 들어있는지 확인하고, 만약 있다면 몇번 째 순서에 해당 문자열이 있는지 알려준다.
  • 해당 문자열이 없다면 -1을 반환
  • 댓글에 욕설이 포함되면 달지 못하도록 차단할 때 사용할 수 있다!

3) slice: 슬라이스는 한국어로 자르다...

  • slice는 말그대로 문자열을 잘라주는 함수
  • 구조는 다음과 같다. slice(잘릴 시작위치, 잘릴 끝위치)
  • 잘릴 끝위치가 조금 헷갈리는데, 잘릴 끝위치의 문구는 포함하지 않는다.

4) string <-> number 전환

(1) string -> number

  • Number(), parseInt(), parseFloat()
parseInt("1.901");
parseFloat("1.901");
Number("1.901");
parseInt("200") + 1;
  • 마이너스 연산의 특성을 활용
var numberAsNumber = "1234"; 
var numberAsString = numberAsNumber - 0;
 
console.log(numberAsNumber, typeof numberAsNumber);
console.log(numberAsString, typeof numberAsString);

(2) number -> string

  • toString()
var numberAsNumber = 1234; 
var numberAsString = numberAsNumber.toString();
 
console.log(numberAsNumber, typeof numberAsNumber);
console.log(numberAsString, typeof numberAsString);
  • 플러스 연산의 특성을 활용
var numberAsNumber = 1234; 
var numberAsString = 1234 + "";
 
console.log(numberAsNumber, typeof numberAsNumber);
console.log(numberAsString, typeof numberAsString);

5. 논리연산자

if (age > 65 || age < 21 && res === "한국")

이러한 조건문이 있다면, 왼쪽에서부터 차례대로 실행된다. 즉, 첫번째 ||에서 나뉘어서 이를 기준으로 둘 중 하나만 참이면 true가 된다. 즉,

  • 65세가 넘거나
  • 21세 아래이고 한국에 산다
    중에 하나만 참이면 조건을 충족하게 된다.

<참인 경우>

  • 66세이다
  • 11세이고 한국에서 산다.

이와 같이 여러조건을 나열하면 가독성이 떨어지고 헷갈리니 웬만하면 괄호로 묶어주는 습관을 가지는 것이 좋다. 바로 이렇게!

if (age > 65 || (age < 21 && res === "한국"))

Assignment
rockPaperScissors 함수를 구현해서 가위 바위 보 게임을 구현해주세요.
가능하면 || 와 && 연산자 둘다 사용해주세요.
player1과 player2 중 이긴 사람이 누군지 리턴해주세요.
예를 들어, player1이 이겼으면 "player1" 이 리턴 되고 그 반대의 경우라면 "player2"가 리턴이 되어야 합니다.
만일 비기는 경우에는 무조건 "player1"이 리턴 되어야 합니다.

풀이

function rockPaperScissors(player1, player2) {
  // 예제:
  if ( (player1 === "가위" && player2 === "보" ) || (player1 == "바위" && player2 == "가위") || (player1 === "보" && player2 === "바위") || (player1 === "가위" && player2 === "가위" ) || (player1 == "바위" && player2 == "바위") || (player1 === "보" && player2 === "보") ){
     return "player1";
  } else {
    return "player2";
  }
}

6. For문

아래 문제는 두고두고 유용하게 사용할 것 같아서 일단 박제해본다!

Assignment
함수 findSmallestElement 의 arr 인자는 숫자 값으로만 이루어진 배열입니다.
arr 의 값들 중 가장 작은 값을 리턴 해주세요.
만일 arr 가 비어있으면 0을 리턴 해주세요.

풀이

function findSmallestElement(arr) {
  // your code here
  if (arr.length === 0){
    return 0;
  } else {
    let num = arr[0]; //임의의 최솟값 지정
    for (i = 0; i < arr.length; i++){
      if(arr[i] < num){
        num = arr[i]; //임의의 최솟값보다 작은 값이 있을 경우 최솟값 재할당
      } 
    }
    return num;
  }
}

7. 배열

1) 인덱스로 요소 수정/추가

let cities = [];
cities[0] = "서울"; // ["서울"]
cities[1] = "대전"; // ["서울", "대전"]
cities[2] = "대구"; // ["서울", "대전", "대구"]
cities[5] = "제주도"; //["서울", "대전", "대구", undefined, undefined, "제주도"]
cities[5] = "포항"; //배열 요소를 수정하기
console.log(cities[5]); // 포항

2) push/unshift: 요소의 추가

  • pushunshift는 모두 배열에 요소를 추가해주는 메소드! 둘의 차이는 요소들이 배열에 추가되는 위치가 다르다는 것!
  • push: 배열의 마지막 부분에 요소를 추가한다.
  • unshift: 배열의 맨 앞 부분에 요소를 추가한다.
let cities = [];
cities.push("경주", "전주");
cities.unshift("인천");

console.log(cities); //["인천", "경주", "전주"]

3) pop: 요소의 제거

  • pop메서드를 통해 배열의 마지막 요소를 제거할 수 있다.
  • 제거할 뿐만 아니라, 제거된 값을 반환까지 해준다.
cities.pop();
console.log(cities); ////["인천", "경주"]

let lastCity = cities.pop();
console.log(lastCity); //"전주"

4) map: 배열 순회해서 수정하기

  • map 메서드는 배열을 반복해서, callback함수에서 return한 값으로 매 요소를 수정해준다.
  • map 메서드의 return값은 수정된 값으로 다시 생성된 배열이다.
  • map은 array타입의 데이터를 요소 갯수 만큼 반복한다.
  • 반복할 때마다 실행할 함수는 parameter로 전달한다.
  • 그러면 이 콜백함수에서 배열의 요소를 인자로 받는다.
  • 해당 요소를 수정하고 싶은대로 로직을 구현하고 리턴해주면 해당 인덱스의 요소가 리턴된 값으로 치횐된다.
const arr = [1, 2, 3];

const squares = arr.map(function (x) { 
  return x * x;
});

console.log(squares) //[ 1, 4, 9 ]

5) forEach: 리턴없는 반복문

  • forEach 메서드는 리턴하는 것이 없다.
  • 그냥 for 대신 사용하는 반복 메서드라고 생각하면 된다.
  • 반복문을 종료하고 싶으면 return하면 된다.
arrb.forEach((el, idx) => {
  if (el === 'c') {
    idxOfC = idx;
    return;
  }
});

console.log(idxOfC) // 2

8. 데이터 타입

//null은 빈 객체를 참조하고 있다.
console.log(typeof null); //"object"
// array는 확장된 객체이다.
console.log(typeof array); //"object"

1) 여러 데이터 타입의 boolean 값 변환

✔️ true 로 변환되는 값

  • 문자열 : 비어 있지 않은 모든 문자열
  • 숫자 : 0 이 아닌 모든 숫자
  • 객체: 모든 객체 ({ }, [ ] 포함)

✔️ false 로 변환되는 값

  • 문자열 : " " (빈문자열)
  • 숫자 : 0, NaN
  • 객체 : null
  • undefined

9. 날짜와 시간

Assignment
만으로 계산한 나이를 구하는 함수인 getWesternAge 함수를 구현해 봅시다.
이 함수는 birthday 라는 인자를 받습니다.
이 birthday 는 Date 객체 입니다. birthday 라는 인자를 넣었을 때, 현재를 기준으로 만으로 계산한 나이를 리턴 해주세요.

풀이

function getWesternAge(birthday) {
  //오늘의 날짜 데이터 만들기
  const dateToday = new Date();
  //세는 나이 구하기
  const year = dateToday.getFullYear() - birthday.getFullYear()
  // 오늘의 날짜가 생일날짜보다 크거나 같으면 세는 나이 그대로, 작으면 한살 빼주기
  if(dateToday.getMonth() >= birthday.getMonth() || (dateToday.getMonth() == birthday.getMonth() && dateToday.getDate() >= birthday.getDate())){
    return year;
  }else{
    return yaer -1;
  }
};

10. Number

1) round, ceil, floor

//round
console.log(Math.round(2.5)); //3
console.log(Math.round(2.49)); //2
console.log(Math.round(2)); //2
console.log(Math.round(2.82)); //3
//ceil
console.log(Math.ceil(2.5)); //3
console.log(Math.ceil(2.49)); //3
console.log(Math.ceil(2)); //2
console.log(Math.ceil(2.82)); //3
//floor
console.log(Math.floor(2.5)); //2
console.log(Math.floor(2.49)); //2
console.log(Math.floor(2)); //2
console.log(Math.floor(2.82)); //2

Assignment
최소(min), 최대값(max)을 받아 그 사이의 랜덤수를 return 하는 함수를 구현해주세요.

풀이

function getRandomNumber (min, max) {
  return Math.round(Math.random()*(max-min)+min)
}

11. Object

1) 객체

  • 키는 마치 특정 값을 갖고 있는 변수같은 역할을 한다.

2) 객체에 접근하는 법

let plan1 = {   
  name: "Basic"
};

console.log(plan1.name); //dot notation  
console.log(plan1["name"]); //bracket notation
  • bracket notation:
    • 동적으로 접근할 때 사용됨.
    • 계산된 결과로 접근한다.
    • 키 값이 공백, 특수문자를 포함한 경우, 변수로 접근할 경우 또는 숫자인 경우 브라켓 노테이션으로 접근한다.
  • dot notation:
    • 정적으로 접근할 때 사용됨.

3) 객체는 reference로 저장된다.

  • 객체를 변수에 저자하면 객체자체가 저장되는 것이 아니라, reference가 저장된다.
  • 그래서 객체를 담은 변수를 비교하면 서로 같지 않다고 나온다.
  • 그러나 객체 내부의 프로퍼티 값이 텍스트일 경우는, 텍스트를 비교하게 되어 서로 같음 / 다름 여부를 판단할 수 있다.
const mutableObj = {
  name: '객체'
};
 
mutableObj = {
   name: '수정'
}
 
mutableObj.name = '수정 됩니다!';
  • const로 선언된 변수는 절대 바뀌면 안되기 때문에, mutableObj에 새로운 객체를 할당하면 오류가 난다. 왜냐하면 새로운 메모리 주소로 수정을 시도하기 때문이다!
  • 하지만, mutableObj.name로 프로퍼티에 접근해서 데이터를 수정하는 것은 가능하다.
  • mutableObj가 저장된 reference가 바뀌는 것이 아니라 객체 내부의 프로퍼티 값이 수정되는 것이기 때문.

Assignment
getData 함수는 세 개의 배열을 인자로 받습니다(salesArr : 날짜별 판매량, reviewArr : 날짜별 리뷰수, likeArr : 날짜별 좋아요수). 다음 요구사항을 충족하는 객체를 만들어서 return 해주세요. 리턴되는 객체는 아래와 같이 3개의 property를 가집니다.(sumAmount : 총 판매량, sumReview : 총 리뷰 개수, sumLike : 총 좋아요 수)

풀이

function getData(salesArr,reviewArr,likeArr){
let obj = {};
let salesSum = 0;
let reviewSum = 0;
let likeSum = 0

for(i=0; i < salesArr.length; i++) {
salesSum += salesArr[i][1];
};

for(i=0; i < reviewArr.length; i++) {
reviewSum += reviewArr[i][1];
};

for(i=0; i < likeArr.length; i++) {
likeSum += likeArr[i][1];
};

obj.sumAmount = salesSum;
obj.sumReview = reviewSum;
obj.sumLike = likeSum;

return obj;
}

>**Assignment**
getAnswer 함수는 아래의 객체에서 '샐러드' 라는 값을 출력합니다.
```js
let myProfile = {
  name: '김개발',
  address: {
    email: '[email protected]',
    home: '위워크'
  },
  'my favorite': {
    food: [{
      name: '샐러드',
      price: 3500
    }, {
      name: '삼겹살',
      price: 15000
    }],
    hobby: ['축구']
  }
}

풀이

function getAnswer() {
  let salad = myProfile['my favorite'].food[0].name;
  return salad
}

4) 객체 순회하기

(1) Object.keys(), Object.values, Object.entries

  • Object.keys()는 어떤 객체가 가지고 있는 키들의 목록을 배열로 리턴하는 메소드
  • 객체 생성자인 Object가 직접 가지고 있는 메소드
const obj = {
  name: 'melon',
  weight: 4350,
  price: 16500,
  isFresh: true
}

Object.keys(obj) // ['name', 'weight', 'price', 'isFresh']

- 이 메소드가 리턴하는 값은 배열이기 때문에 이걸로 반복문을 사용할 수 잇다.

```js
const keys = Object.keys(obj) // ['name', 'weight', 'price', 'isFresh']

for (let i = 0; i < keys.length; i++) {
  const key = keys[i] // 각각의 키
  const value = obj[key] // 각각의 키에 해당하는 각각의 값
  console.log(value)
}
  • 새로운 ES6 문법에서는 Object.keys 외에도 마찬가지로 Object생성자의 메소드인 Object.values, Object.entries 와 같은 자매품들이 추가되었다.
  • Object.values 는 객체의 키가 아닌 값으로 이루어진 배열을 리턴한다. Object.entries 는 객체의 키와 값의 쌍으로 이루어진 길이 2짜리 배열로 이루어진, 배열을 리턴한다.

(2) for-in

  • 반복문인 for문과 같은 종류의 문법이지만, 객체와 배열을 위해 특별히 존재하는, ES6 에서 추가된 문법
const arr = ['coconut', 'banana', 'pepper', 'coriander']
 
for (let i = 0; i < arr.length; i ++) {
  console.log(i+":"+ arr[i]) // 0:coconut 1:banana 2:pepper 3:coriander
}

for (let i in arr) {
  console.log(i+":"+ arr[i]) // 0:coconut 1:banana 2:pepper 3:coriander
}
  • 이 for-in 문은 인덱스의 값으로 무엇을 할당하고, 반복문이 몇번 돌아야 할 지를 자바스크립트 엔진 내부에서 자동으로 결정하게 된다.
const obj = {
  name: 'melon',
  weight: 4350,
  price: 16500,
  isFresh: true
}

for (let key in obj) {
  const value = obj[key]

  console.log(key)
  console.log(value)
  //name
  //melon
  //weight
  //4350
  //price
  //16500
  //isFresh
  //true
}

12. Class

1) Class 개념

클래스는 객체지향 프로그래밍의 핵심. 객체지향 프로그래밍이란, 프로그램을 객체들로 구성하고, 객체들 간에 서로 상호작용 하도록 작성하는 방법을 뜻함. 클래스는 객체를 잘 설계하기 위한 틀임. 이때 객체는 특정 로직을 갖고있는 행동(메서드)와 변경가능한 상태(멤버 변수)를 가진다. 이에 맞춰 원하는 구조의 객체 틀을 짜놓고, 비슷한 모양의 객체를 공장처럼 찍어낼 수 있도록 하는 것이 클래스이다.

let ray = {  
  name: 'Ray',  
  price: 2000000,   
  getName: function() {  
    return this.name;  
  },   
  getPrice: function() {  
    return this.price;  
  },   
  applyDiscount: function(discount) {  
    return this.price * discount;   
  } 
}
  • 위와 같이 객체의 프로퍼티 값에는 함수도 넣을 수 있다. 이때 함수는 아래와 같이 호출 할 수 있다.
const rayPriceByFunction = ray.getPrice();
console.log('함수로 접근 => ' +rayPriceByFunction);
  • 객체의 내부에서 해당 객체의 프로퍼티에 접근하려면 this라는 키워드를 사용할 수 있다.

2) 클래스를 이용해서 객체 생성하기

클래스 생성하기

class Car {
  constructor(name, price) {
    this.name = name;
    this.price = price;
    this.department = "선릉지점";
    this.salesAmount = 0;
  }

  applyDiscount(discount) {  
    return this.price * discount;   
  }
  
  addSales() {
    this.salesAmount++;
  }
}

객체 생성하기

const morning = new Car('Morning', 2000000);
console.log(morning); //morning: [object Object]
console.log(morning.name); //Morning
console.log(morning.price); //2000000

const price = morning.applyDiscount(0.8); 
console.log(price); //1600000

console.log(morning.salesAmount); //0
morning.addSales();
console.log(morning.salesAmount); //1

3) 생성자(constructor)

  • 객체와 객체의 설계도인 클래스는 문법이 매우 비슷하나, 그 둘의 가장 큰 차이는 constructor라는 생성자 함수이다.
  • 아래와 같이 class로 객체를 생성하는 과정을 '인스턴스화'라고 부른다.
const morning = new Car('Morning', 2000000);
  • 클래스를 통해 생성된 객체를 인스턴스라고 부른다.
  • 클래스는 새로운 인스턴스를 생성할 때 마다 constructor()메서드를 호출한다.
class Car {
  constructor(name, price) {
    this.name = name;
    this.price = price;
  }
}
  • Car는 클래스의 이름이다. 항상 대문자로 시작하며 CamelCase로 작성해야 한다.
  • Car class의 instance를 생성할때마다 constructor 메서드가 호출된다.
  • constructor() 메서드에 this 키워드를 사용했다. class의 실행범위(context)에서 this 는 해당 instance를 의미합니다.
  • constructor() 에서 인자로 넘어오는 name과 price를 사용해 Car instance의 name, price 프로퍼티에 값을 할당했다.
  • 이렇게 클래스 내에서 name, price와 같이 변경 가능한 상태값이자 class내의 컨텍스트에서 어느 곳에서나 사용할 수 있는 변수를 '멤버 변수'라고 부른다.
  • 멤버 변수는 this키워드로 접근한다.

4) 인스턴스

const morning = new Car('Morning', 20000000);
  • 인스턴스는 Class 이름에 new를 붙여 생성한다.
  • 클래스 이름 우측에 () 괄호를 열고 닫고, 내부에는 constructor 에서 필요한 정보를 인자로 넘겨준다.
  • new 키워드는 constructor() 메서드를 호출하고 새로운 instance를 return해준다.

좋은 웹페이지 즐겨찾기