JS2

KwangYong·2021년 12월 14일
0

JavaScript

목록 보기
2/3

👨🏻‍🏫 클래스와 오브젝트의 차이점(class vs object)

source : 드림코딩 js기초6
class에는 fields와 methods가 들어있는데 그 fields만 들어있는 경우 data class라고 불린다. 캡슐화, 상속, 다형성.
class는 template, 청사진이라고도 불림. class자체에는 데이터가 들어있지 않고 틀만 정해놓음.
이 class에 실제로 데이터를 넣어서 만드는 것이 object다. 그래서 클래스를 이용해서 새로운 인스턴수를 생성하면 object가 된다.

object-oriented programming
class: template
object: instance of a class
JavaScript classes
-introduced in ES6
-syntactical sugar over prototype-base inheritance
js에 class는 추가된지 얼마되지 않음. 그 전에는 클래스를 정의하지 않고 object를 만들었고 function을 이용해서 템플릿을 만들었음. class는 완전히 새롭게 추가된것이 아니라 기존의 프로토타입을 베이스로 그 위에 우리가 간편하게 쓸 수 있도록 문법만 클래스가 추가된 것이다. 문법상으로 달달한 편리함(syntactical sugar)

1. Class declaration

class Person{
//constructor
constructor(mname, age){
//fields
this.mname = name;
this.age = age;
}
//method
speak(){
console.log(${this.mname}: hello!);
}
}
const ellie = new Person('ellie', 20);
console.log(ellie.name);
console.log(ellie.age);
ellie.speak();

2. Getter and Setter

setter는 사용자의 입력범위를 제한함.
getter를 정의하는 순간 this.age는 메모리에 올라가 있는 데이터를 읽어오는 것이 아니라
바로 getter를 호출하게 된다.
setter를 정의하는 순간 equal sign ()= age;) 즉, 값을 할당할 때 바로 메모리에
값을 할당하는 것이 아니라 setter를 호출한다.
그래서 getter와 setter는 메모리에 값을 할당하는 것이 아니라 계속 setter getter 무한 호출로 콜 스택이 초과됨.
따라서 getter, setter안에서 쓰이는 변수의 이름을 조금 다른 걸로 만들어줘야한다.
⭐ 결국 User class안의 fields는 firstName, lastName, _age 3개다.
field에는 _age지만 우리가 .age라고 호출할 수 있는 것, 그리고 .age에 값을 할당할 수 있는 것은 내부적으로 getter와 setter를 이용하기 때문임.

class User {
    constructor(firstName, lastName, age) {
        this.firstName = firstName;
        this.lastName = lastName;
        this.age = age;
    }
    get age(){
        return this._age;
    }
    set age(value){
        // if(value < 0){
        //     throw Error('age can not be negative');
        // }
        this._age = value < 0 ? 0 : value;
    }
}
const user1 = new User('Steve', 'Jobs', -1);
console.log(user1.age);

3. Fields (public, private)

너무 최근에 추가됨.

class Experiment {
    publicField = 2; //public
    #privateField = 0;// private 외부에서 접근 불가능
}
const experiment = new Experiment();

4. Static properties and methods

너무 최근에 추가됨.
object와 데이터에 상관없이 클래스에서 동일하게 반복적으로 사용되어지는 field와 method에 static키워드를 붙인다.

class Article{
    static publisher = 'Dream coding';
    constructor(articleNumber) {
        this.articleNumber = articleNumber;
    }
    static printPublisher() {
        console.log(Article.publisher);
    }
}
console.log(Article.publisher);
Article.printPublisher();

5. Inheritance

a way for one class to extend another class

class Shape {
    constructor(width, height, color){
        this.width = width;
        this.height = height;
        this.color = color;
    }
    draw() {
        console.log(`drawing ${this.color} color of`);
    }
    getArea(){
        return width * this.height;
    }
}

class Rectangle extends Shape {}
class Triangle extends Shape {
    draw (){ // 오버라이딩
        super.draw(); //부모의 super 호출
        console.log('?');

    }
    getArea(){ //오버라이딩
        return (this.width*this.height) / 2; 
    }
    toString(){ //오버라이딩
        return `Triangle: color: ${this.color}`;
    }
}

const rectangle = new Rectangle(20, 20, 'blue');
rectangle.draw();
const triangle = new Triangle(20, 20, 'red');
triangle.draw();

6. Class checking : instanceof

object가 해당 클래스를 이용해서 만들어진 instance인지 확인

console.log(rectangle instanceof Rectangle);
console.log(triangle instanceof Triangle);
console.log(triangle instanceof Rectangle);
console.log(triangle instanceof Shape);
console.log(triangle instanceof Object); //js의 모든 object는 Object를 상속받음.
console.log(triangle.toString());

👍 js reference MDN : https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference

👨🏻‍🏫 오브젝트 Object

source : 드림코딩 js기초7

Objects
one of the JavaScript's data types.
a collection of related data and/or functionality.
Nearly all objects in JavaScript are instances of Object.
object = {key : value};
오브젝트는 key와 value의 집합채.

1. Literals and properties

object는 중괄호를 이용해서 생성 또는 new 키워드 Object 클래스로 생성
첫번째 방법을 'object literal' syntax
두번째 방법을 'object constructor' syntax

const obj1 = {}; //'object literal' syntax
const obj2 = new Object();//'object constructor' syntax
function print(person){
    console.log(person.mname);
    console.log(person.age);
}
const ellie = {mname: 'ellie', age: 4};
//클래스가 없어도 괄호를 이용해서 오브젝트 생성
print(ellie);

with JavaScript magic(dynamically typed language)
con add properties laters
js는 런타임때 타입이 결정되므로
object 선언한 뒤에 프로퍼티를 추가하거나 삭제할 수 있다.

ellie.hasJob = true;
delete ellie.hasJob;

2. Computed properties 계산된 프로퍼티

object안의 데이터를 접근할 때 '.'을 이용하거나 대괄호안에 스트링 형태의 데이터 이름으로 접근 가능.
후자의 방법을 Computed properties라고 함. 이때 key should be always string
전자의 방법은 코딩하는 그 순간 그 key에 해당하는 값을 받아오고 싶을때 사용.
Computed properties는 우리가 정확하게 어떤 key가 필요한지 모를 때 즉, 런타임에서 결정될 때 사용한다.
다시 말해, 실시간으로 원하는 key의 값을 받아오고 싶을 때 사용.

console.log(ellie.name);
console.log(ellie['name']);//object안의 변수 이름의 스트링 형태로 접근 가능.
ellie['hasJob'] = true; //computed properties를 이용한 프로퍼티 추가

⭐ 사용자에게 특정 key를 input받아서 value를 출력해야하는 함수라면
코딩하는 시점에는 어떤걸 출력할지 전혀 모른다.
그래서 이때는 computed properties를 써야한다.
동적으로 key에 관한 value를 받아와야할 때 유용하게 사용한다.

function printValue(obj, key){
    // console.log(obj.key); -> object에 'key'라는 프로퍼티가 들어있지 않으므로 undefined 리턴
    console.log(obj[key]);
}
printValue(ellie, 'name');

3. Property value shorthand

function에서 object 리턴할 때 key와 value가 동일하다면 생략할 수 있음.

const person1 = {mname: 'bob', age: 2};
const person2 = {mname: 'bob', age: 2};
const person3 = {mname: 'bob', age: 2};

object가 필요할때 일일이 만들게 되면 반복되는 key를 계속 작성해야하는 불편.
그래서 값만 전달해주면 object를 만드는 함수를 만듦.
즉, class(template)과 같은 역할.

const person4 = makePerson('ellie', 30);
console.log(person4);
function makePerson(name, age){
    return { //object를 리턴
        name, //key와 value가 동일하면 생략 가능.
        age,
    };
}

4. constructor function

그래서 다른 계산을 하지 않고 순수하게 object를 생성하는 함수들은 class처럼 대문자로 시작하는 name으로 만들고 return을 하지 않고 constructor에서 했던 것처럼 this.name=name; 으로 작성함.
그리고 호출할때도 new 키워드를 사용해서 new Person()으로 사용한다.
js엔진이 알아서 object를 생성함.

const person5 = new Person('kwang', 29);
console.log(person5);
function Person(name, age){
    // this = {}; -> 생략된 부분: 새로운 object 생성 
    this.name = name;
    this.age =age;
    //return this; -> 생략
}

5. in operator: property existence check (key in obj)

obj안에 해당 키가 있는지 확인

console.log('name' in ellie);

6. for..in vs for..of

for(let key in ellie){ //key들을 하나씩 받아옴
    console.log(key);
}

//for (value of iterable)
//object를 쓰는 것이 아니라 배열과 같은 순차적인 구조에 해당.
const array = [1,2,3,4];
for(let value of array){
    console.log(value);
}

7. Fun cloning

Object.assign(dest, [obj1, obj2, obj3...])
🍀 object를 할당하게 되면 같은 obj를 가리키게 된다.

const user = {mname: 'ellie', age: '20'};
const user2 = user;
user2.mname = 'kwang';
console.log(user);

🍀 그럼 obj 내용을 복사하는 방법은? cloning

old way: 빈 obj를 만들고 수동으로 반복하면서 value를 할당.

const user3 ={};
for(let key in user){
    user3[key] = user[key]; //새로운 프로퍼티 key를 만들고 value를 넣는다.
}
console.log(user3);

Object.assign(붙여넣기할 target, 복사되는 변수) 그리고 섞인 변수가 리턴.

const user4 = Object.assign({}, user);
console.log(user4);

another example

const fruit1 = {color : 'red'};
const fruit2 = {color : 'blue', size: 'big'};
const mixed = Object.assign({}, fruit1, fruit2);
console.log(mixed.color); //뒤에 나오는 변수가 있고 동일한 프로퍼티가 있다면 값을 계속 덮어씌워진다.
console.log(mixed.size);

👨🏻‍🏫 배열 개념과 APIs

👀 object와 자료구조의 차이점: object는 서로 연관된 특징과 행동들을 묶어 놓는 것. 그리고 비슷한 타입의 object들을 묶어놓는 것을 자료구조라고 함. 다른 언어에서는 동일한 타입의 object만 자료구조에 담을 수 있지만 js는 dynamically typed language기 때문 한 바구니 안에 여러 타입의 데이터를 담을 수 있다. 하지만 그렇게 하지 않는 것이 좋다.
source : 드림코딩 js기초8

1. Declaration

const arr1 = new Array();
const arr2 = [1,2];

2. Index position

const fruits = ['🍎' , '🍌'];
console.log(fruits);
console.log(fruits.length);
console.log(fruits[0]);
console.log(fruits[fruits.length -1]);
console.clear();

3. Looping over an array

a. for

for (let i = 0; i < fruits.length; i++){
    console.log(fruits[i]);
}

b. for of

for (let fruit of fruits){
    console.log(fruit);
}

c. for each

배열 안의 value들마다 내가 전달한 함수를 실행한다.

fruits.forEach(function (fruit, index) {
    console.log(fruit, index);
});

anonymous function은 arrow함수 쓸 수 있다.
한 줄의 경우, 괄호와 세미콜론 필요없다.

fruits.forEach((fruit, index) => console.log(fruit, index));

4. additon, deletion, copy

push: add an item to the end

fruits.push('🍓','🍑');

pop: remove an item from the end

삭제하고 그 삭제된 원소를 리턴함.

fruits.pop();
fruits.pop();
console.log(fruits);

unshift: add an item to the beginning

fruits.unshift('🍆', '🌽');
console.log(fruits);

shift: remove an item from the beginning

fruits.shift();
fruits.shift();
console.log(fruits);

📌 note!! shift, unshift are slower than pop, push
맨 앞을 삽입하거나 삭제하기 위해서 그 뒤의 모든 원소를 밀어내거나 당겨와야하기 때문에 오래걸린다.

splice: remove an item by index position

splice(시작 인덱스, 삭제할 개수): '삭제할 개수'를 지정 안하면 시작인덱스부터 끝까지 지운다.
splice(시작 인덱스, 삭제할 개수, 삽입원소1, 삽입원소2...): 또한 삭제한 그 자리에 새로운 원소 삽입 가능.
그리고 return은 삭제된 요소들이 리턴.
삭제할 개수가 0인 경우, 삽입만 할 수 있다.

fruits.push('🥑', '🍋', '🍊');
fruits.splice(1, 1);
console.log(fruits);
fruits.splice(1, 1, '🍏','🍐');
console.log(fruits);

concat: combine two arrays

const fruits2 = ['🍒','🌶'];
const newFruits = fruits.concat(fruits2);

5. serching

indexOf: find the index

includes

console.log(fruits.indexOf('🍎'));
console.log(fruits.includes('🍌')); // false, 해당 원소가 포함되어있는지

lastIndexOf: 해당 원소가 2개이상일 때 마지막 원소의 인덱스를 리턴

fruits.push('🍎');
console.log(fruits.indexOf('🍎'));
console.log(fruits.lastIndexOf('🍎'));

👨🏻‍🏫 유용한 10가지 배열 함수들, Array APIs

source : 드림코딩 js기초9

// Q1. make a string out of an array
{
    const fruits = ['apple', 'banana', 'orange'];
    const res = fruits.join();
    console.log(res);
  }
  
  // Q2. make an array out of a string
  {
    const fruits = '🍎, 🍌, 🍒, 🍏';
    const res = fruits.split(',', 2); //2 -> 앞에서 두개만 나오도록 제한할 수 있다.
    console.log(res); 
  }
  
  // Q3. make this array look like this: [5, 4, 3, 2, 1]
  {
    const array = [1, 2, 3, 4, 5];
    const res = array.reverse();
    console.log(res);
    console.log(array);//기존 배열도 reverse된다
  }
  
  // Q4. make new array without the first two elements
  {
    const array = [1, 2, 3, 4, 5];
    //splice는 제거된 원소들의 배열을 리턴하고 기존 배열은 남은 원소들로 변경된다
    const res = array.splice(0, 2);
    console.log(res);
    console.log(array);

    //slice는 배열의 특정부분을 배열로써 리턴하고 기존 배열을 변하지 않는다.
    //end index는 제외된다는 점을 주의하자.
    //Returns a copy of a section of an array.
    const array2 = [1, 2, 3, 4, 5];
    const res2 = array2.slice(2, 5);
    console.log(res2);
    console.log(array2);
  }
  
  class Student {
    constructor(name, age, enrolled, score) {
      this.name = name;
      this.age = age;
      this.enrolled = enrolled;
      this.score = score;
    }
  }
  const students = [
    new Student('A', 29, true, 45),
    new Student('B', 28, false, 80),
    new Student('C', 30, true, 90),
    new Student('D', 40, false, 66),
    new Student('E', 18, true, 88),
  ];
  
  // Q5. find a student with the score 90
  {
      //find: Returns the value of the first element in the array where predicate is true, and undefined
      //콜백함수가 true를 리턴하면 즉시 중단하고 그때의 원소를 리턴함.
      const res = students.find((student) => student.score === 90);
      console.log(res);
  }
  
  // Q6. make an array of enrolled students
  {
      //filter: Returns the elements of an array that meet the condition specified in a callback function.
      //조건에 맞는 원소들을 리턴한다. 콜백함수에서 true를 리턴하면 조건에 맞는거다.
      const res = students.filter((student) => student.enrolled);
      console.log(res);
  }
  
  // Q7. make an array containing only the students' scores
  // result should be: [45, 80, 90, 66, 88]
  {
      //map: 배열의 각 원소들을 콜백함수로 가공한 뒤 return하고 그 원소들(results)의 배열을 리턴함.
      const res = students.map((student) => student.score);
      console.log(res);
  }
  
  // Q8. check if there is a student with the score lower than 50
  {
      //some: 배열의 각 원소들에 대해 콜백함수에서 true를 리턴하는 원소가 있는지 탐색함.
      const res = students.some((student) => student.score < 50);
      console.log(res);

      //every: 배열의 모든 원소들이 콜백함수에서 true를 return하는지 확인.
      const res2 = !students.every((student) => student < 50 );
      console.log(res2);
  }
  
  // Q9. compute students' average score
  {
      //reduce: 누적된(accumulated) 정보를 얻을 때 사용함.
      //리턴된 값을 다음 콜백함수의 prev인자로 씀.
      //초기값(init) 설정있음.
    
    //   const res = students.reduce(function(prev, curv) {
    //     return prev + curv.score;
    //   }, 0);

      const res = students.reduce((prev, curr) => prev + curr.score, 0);
      console.log(res / 5);
  }
    
  
  // Q10. make a string containing all the scores
  // result should be: '45, 80, 90, 66, 88'
  {
      const res = students.map((student) => student.score).join();
      console.log(res);
  }
  
  // Bonus! do Q10 sorted in ascending order
  // result should be: '45, 66, 80, 88, 90'
  {
      //sort: 이 메서드는 배열을 변경하고 동일한 배열에 대한 참조를 반환합니다.
      //a - b에서 음수가 나오면 b가 크다는 뜻이므로 정렬된다.
      const res = students.map((student) => student.score)
      .sort((a, b) => a - b)
      .join();
      console.log(res);
  }
profile
바른 자세로 코딩합니다 👦🏻💻

0개의 댓글