수업 5일차

galoo·2023년 7월 4일
0
post-thumbnail

✔ Object(객체)

  • 변수 : 데이터의 개념

  • 속성 : 성질을 나타내는 것

  • 변수는 혼자 존재해도 가능하지만, 속성은 단독으로 존재하면 의미를 가질 수 없다.

  • 속성(attribute, property, column, field)
    - table에서 세로 방향인 것

  • 함수 vs 메서드 : 리시버가 있느냐 없느냐 차이였다.

객체의 종류

  • 사용자 정의 객체 : 직접 생성
  • 내장 객체 : 일반 객체, BOM(브라우저 관련), DOM(문서 관련,body부분)
  • 3rd Party 객체 : 외부 라이브러리에서 제공하는 객체

사용자 정의 객체

  • 똑같은 데이터의 모임 : []
  • 키와 값의 모임 : {속성이름 : 데이터, ....}
  • 객체 생성 :
    사용자 정의 객체 생성 : var(let, const) 객체명 = {속성이름:데이터,..}
    built-in obj나 직접 생성자 만든 경우 : var 객체명 = 생성자메서드(매개변수)

  • 객체의 요소 접근
    - 객체명[속성이름] or 객체명.속성이름(이것을 권장합니다.)
    - why? : 후자가 대부분의 언어에서 지원하기 때문입니다.

  • function - method
    - 속성 안에 메서드를 작성하거나 대입하는 것이 가능
    - 객체를 통한 내부 메서드 호출 : 객체.메서드(매개변수)

  • CRUD

  • upsert : 있는 속성이라면 update, 없다면 insert

  • delete : 지우고 싶은 객체이름.속성

  • 코드 예시

let human=[{name:"이민호",age:26,gender:"male"},
{name:"최종원",age:26,gender:"male"}]
let human2={name:"이민호",age:26,gender:"male"}
// 이렇게 출력시, type을 보여준다. 속성까지 가야지 값을 보여준다.
document.write(human) 
// 이래야 값이 나오겠지?
document.write(human[0].name, human[0].age, human[0].gender) 
//이건 for문으로 둘다 출력하기야
for(let i=0; i<2; i+=1){
          document.write(human[i].name, human[i].age, human[i].gender)
          document.write("<br/>")
}

이렇게 python에서도 위와 같이 사용자 정의 객체를 선언한다.

이때 document.write(human) 을 출력하면 다음과 같다.
[object Object]
이는 앞에는 자료형 뒤에는 실제 변수명인데 지을게 없어서 오브젝트라 한거야.

?
나는 배열 한칸에 속성을 3개나 넣어놨는데 왜 한개치만 나오는거지?
그건 바로 human배열의 BOF(Begin of File)을 가리키고 있기에 한개만 나오는 거야. 맨 끝은 EOF(End of File) 이다. for문은 EOF를 만날때 까지이다. 결국 하나만 나온 건 BOF를 가리키기 때문에 맨 처음 하나만 나온거야.

[] : 배열 리스트, {} : 객체
배열은 index를 가지고, 객체는 이름을 가지고 찾는다.
이름을 가지고 찾는게 더 좋다. 이름을 기억하는게 더 쉽다. 번호보다.

  • 데이터를 보낼 때에는 맨 마지막이 {} 형태여야 한다.
  • 우선 데이터 보낼 때 성공했는지를 먼저 알려주어야 한다.
  • 일관성이 있어야 합니다.(일관성)

메서드 연결하기

  • Function : 전역
  • Method : 제한이 됩니다. (리시버를 통해서만 접근 가능)
    - 이때, 리시버는 Class(다른 객체지향은 static, 파이썬은 둘 다 가능), Instance
    - 객체 자신을 가리키는 포인터가 존재(This(js, java), self(python 관습))
    - python은 instance 메서드 호출방법이 2개래!
    - JS는 this가 너무너무너무 중요합니다.
let obj={name:"mino",disp:function(){
							alert(this.name)
                          }}

이렇게 하지 않으면 name은 출력이 안된단다. undefined로 됩니다.
this\rarr내가 속한 객체에서만 찾는다. 상위클래스는 super이다.

obj.disp(): 호출, obj.disp : 함수의 내용

  • 이 this는 obj야. this에는 근데 obj를 못써 왜냐면 = 계산이 있기 때문에 이게 끝나야 obj를 쓸 수 있는거야.

생성자 함수

  • 동일한 모양의 인스턴스를 편리하게 생성하기 위한 방법
    - Class 이다.

  • 생성자 : new 생성자이름(매개변수) 이게 객체 생성방법

  • new는 프로그래머에게 굉장히 중요하다.

  • new는 heap영역에 만들자는 것이다.

  • heap영역은 가리키는게 없어지면 메모리 해제가 된다.

  • JS 에서 영구적인 부분에는 Function, Class, 문자열상수가 들어가진다.

  • 영구적인부분과 Heap은 합쳐서 용량계산을 한다. 영구적인 부분은 개발자가 바로 부를 수 있다.

  • temporary: Stack은 실행을 위해 임시 저장 영역(Stack은 자료구조)

  • static : 영구적이다 지울 수 었다.

  • dynamic : 썼다가 지웠다 할 수 있다.(Heap 자료구조)

//생성자가 없는 경우 동일한 모양의 2개의 객체 생성
let ar=[
        	{name:"mino", disp:function(){document.write(this.name)}},
        	{name:"mino2", disp:function(){document.write(this.name)}}
        ]
for(idx in ar){
      ar[idx].disp()
      document.write("<br/>")
}
// 잘 찍히긴 하지만 함수가 중복되어 있는 형태이다. 이를 어떻게 해야 할까?
//생성자를 만들어보자. - 왜 생성자야? : 함수 안에서 this를 사용했기 때문이다.
//일반함수는 this를 사용할 수 없다.
let person=function(name){
            this.name=name;
            this.disp=function(){document.write(this.name)}
            }
// 이렇게 한다면 disp를 두번 하는게 아니다. 
//메서드는 다시 만들지 않고 속성만 설정해서 인스턴스 생성하기에 생성자를 쓴다.
//생성자를 이용해서 인스턴스를 만들 떄는 new와 함께 호출해야 한다.
// 그렇게 한다면 heap 공간에 인스턴스를 생성한다.
ar=[new person("mino"),new person("mino2")]
for(idx in ar){
     ar[idx].disp()
     document.write("<br/>")
}

동일한 역할을 하는데 더 효율적인걸?

사용자 정의 객체를 만드는 방법

  • 바로 생성
    - 생성 이름 : 데이터

  • 생성자를 이용하는 방법
    - 함수를 만들 때, 내부에서 this를 이용해서 속성과 메서드를 생성

  • Class를 만들고 생성하는 방법(권장)
    - Class : 동일한 인스턴스를 만들기 위한 모형
    - 만들 때 :
    let 클래스 이름 = class{ constructor(매개변수){내용}메서드 나열}
    - 클래스를 이용해서 인스턴스 생성 방법
    new 클래스이름(매개변수); 클래스 이름을 적지만 실제로는 constructor가 호출
    - Constructor(생성자)는 default로 존재하며, 초기화가 목적임
    python은 __init__이 생성자이다.
    - 생성자 역할 : 1. heap에 공간 할당(allocation), 2. 내부 초기화(init)

// class를 생성하고 인스턴스 생성
let Member = class{ //관습적으로 클래스는 앞글자 대문자
    		 //생성자    
            constructor(name){
                    this.name=name
            }
//클래스 안에 메소드를 만들 때에는 let이나 function 생략 가능합니다.
            disp(){
                document.write(this.name);
                document.write("<br/>");
            }
        }
ar=[new Member("mino"), new Member("mino2")]
for(idx in ar){
     ar[idx].disp()
}

Class가 아니라면 내부 데이터 형태를 직접 확인해야 하는 문제가 있다.
Class가 있다면 내부 데이터가 어떤 것인지 클래스만 보고 판단 가능하다.

Class = 스키마 = 테이블 (릴레이션) : 근본적으로 다 같은 말입니다.
클래스를 설계한다면 디자인패턴, UML등을 공부하게 된다.
스키마, 테이블 설계 : 모델링 이라고 부른다.
\rarr(어떤 것을 하나로 묶는게 가장 효율적인 것일까요?)
하나의 스키마에는 배열이 존재하면 안된다.
modeling을 클래스에서 한다면 객제지향설계라고한다.

{} : 모든 데이터에는 이름이 있어야 하며, meta데이터로 데이터를 설명해주는 것이 있어야 한다.

접근자 메서드 (getter & setter)

  • getter : 속성을 리턴하는 메서드
    - get속성이름 으로 하는 것이 일반적, 속성이름 첫 글자는 대문자
    - 매개변수는 없으며, 속성을 return 하기만 하면 된다.
    - 속성의 자료형이 boolean 인 경우, get대신 is를 사용하기도 한다.
  • setter : 속성의 값을 수정하는 메서드
    - 이름은 set속성이름으로 하는 것이 일반적, 속성이름 첫 글자는 대문자
    - 매개변수는 1개이며, 매개변수의 값을 속성에 대입하기만 하면 된다.
    - 내용을 작성하는 경우가 있는데, 대부분 유효성 검사를 위한 것이다.
let Person =class{
            //이번에는 생성자 parameter가 2개이다.
            constructor(name, score){
                this.name=name;
                this.score=score;
            }
            disp(){
                console.log(this.name+":"+this.score)
            }
            // 은행의 잔액(속성)은 은행원(메서드)를 통해 변경이 가능한 것이다. 
            // 왜냐하면 근본적으로 데이터는 syncronized가 안된다.
            //이를 메서드를 통해서 하는 것이다.
            //getter
            getName(){
                return this.name
            }
            //setter
            setName(name){
                this.name=name
            }
            getScore(){
                return this.score
            }
            setScore(score){
                //유효성 검사 : 올바른 데이터인지 확인하는 것이다.
                if(score<0 || score>100){
                    alert("적절하지 않은 점수입니다!")
                    return // 대입하지 않고 나가버리기
                }
                this.score=score
            }
        }
let obj=new Person("mino",90);
obj.setScore(150);
obj.disp();

common concern & business logic

  • 둘은 명확하게 구분되어야 한다. 실제 업무가 무엇인지 알아두자
  • common concern : 실제 업무와는 상관 없는 작업(나중에 처리되도 된다)
  • business logic : 실제 업무와 관련된 것(바로바로 처리)

Static 메서드

  • 인스턴스가 아니라 클래스가 호출할 수 있는 메서드
  • this를 사용할 수 없음(this는 인스턴스를 가리키는 숨겨진 포인터)
  • 함수 이름 앞에 static만 기재하면 됩니다.
  • 왜 클래스가 부를 수 있는 것을 따로 만들어?
    - 인스턴스는 만들어서 불러야 하지만, 클래스는 안만들고 부를 수 있다.

✔ 상속 (Inheritance)

  • 상속의 유형 큰 두 가지
  1. A 클래스를 만들었어요. b, c 기능이 들어있는
    B 클래스를 만들었어요. c, d 기능이 들어있는
    똑같은거 2개 쓰는건 안좋다.
    Super 클래스 C를 만들어 c 기능을 두고, A,B 클래스에 b와 d만 넣자.
    그리고 작성할 때, A class extends Super{ 하면 된다.

  2. 이미 만들어진 클래스를 상속받는 경우(A\rarrA')
    프로그램을 만들 때 많이 쓰는 애들을 만들어줌(Framework) : A
    A는 기본적인 것만 들어있는 것이다.(한 80% 제공이라 가정하자)
    근데 부족하다고 100%짜리를 새로 만드는 것 보다는
    A를 extends를 하는 것이다. 결국 나는 20%만 만드는 것이다.

  • 같은기능 같은 이름 다른기능 다른이름
  • 상속 시 가장 많이 붙이는건 ex이다. thread_ex 이렇게?

상속이란?

  • 하위 클래스가 상위 클래스의 모든 것을 물려받는 것

용어정리

  • 용어
    - 상속 관계를 객체 지향에서는 is a 관계라고 합니다.
    - has a?
    - 상위 클래스 : super나 base 클래스 (상속하는 클래스)
    - 하위 클래스 : sub 또는 derived 클래스 (상속받는 클래스)
    - 끄집어 올리는것은 추상이다.(abstract)
    - 단일 상속 : 하나의 클래스로부터 상속받는 것
    - 다중 상속 : 2개 이상의 클래스로부터 상속받는 것

다시 돌아와서

let Super =class{ //class Super{}이것도 가능하긴 함
            method(){
                console.log("상위 클래스의 메서드에요")
            }
        }
class Sub extends Super{
   //여긴 method()가 없죠?
}
let obj = new Sub();
obj.method() //하지만 나오죠?
//Sub에는 method가 없지만, 상속을 받아서 호출이 가능함
let Sub2= class extends Super{
}
let obj2=new Sub2();
obj2.method()

오버라이딩

  • 상위 클래스에 존재하는 메서드를 하위 클래스에서 다시 정의하는 것
  • method 재정의 라고 말한다.
  • 추상 메서드(이름만 존재하는 메서드)를 다시 만드는 것은 재정의가 아니고 구현(Implementation)이다.
  • 목적은 기능 추가이다.
    - 새로운 기능을 만든다면 그 때는 이름을 다르게 해야 합니다.

무엇인가를 만들 때에는 Super를 먼저 씁니다.(안쪽)
대신 파괴 할 때에는 Super를 나중에 없애버립니다.(바깥쪽)
\rarr 서브의 메모리를 해제하고 상위의 메모리를 해제해야 한다.
\rarr Super가 먼저 망가지면 안된다.

class Sub extends Super{
            method(){
                super.method();
                console.log("상위 클래스의 메서드 재정의")
            }
}

Super

  • 하위 클래스의 메서드에서 상위 클래스의 메서드를 호출할 때는 super.메서드이름()을 하면 됩니다.

  • 오버라이딩을 한다면 하위 클래스에서는 상위 클래스의 메서드를 호출해야 한다. why?

✔ 다시 Object

Built-In Object

  • JS가 제공하는 객체

종류

  • 일반 객체 : 프로그래밍에 필요한 객체
  • BOM(Browser Object Model) : 브라우저와 관련된 객체
  • DOM(Document Object Model) : body 태그와 관련된 객체
    - DOM은 크롤링하려면 좀 알아야 한다.

일반 객체

  • Object : 최상위 객체
    - JS의 모든 객체는 이 객체를 상속받습니다.
    - 이걸 다 상속 받으면 내가 안쓰는 불필요한 것도 다 상속받는다

Math 객체

  • Math 객체 : 수학과 관련된 기능을 제공하는 객체
  • 이 객체는 인스턴스를 생성하지 않고 사용합니다.
    - Math.속성 또는 메서드이름()dml gudxofh tkdyd
    - Java의 Math 클래스와 동일하게 동작
  • Math.rand()를 호출하면 0.0~1.0 사이의 숫자 중 랜덤 값 리턴합니다.

String 객체

  • 변경할 수 없는 문자열을 저장하기에 모든 메서드가 작업 후에 리턴을 합니다.
  • String 대부분언어에서 하면 안되는 행동이 있습니다.
  • let str="Hello" : 문자열 상수는 static한 영역으로 들어갑니다.
    - str = str + "world" 이는 굉장히 나쁘게 취급합니다.
    - 등호 왼쪽은 이름이 아니기에 "Hello"로 바뀐다. static에 들어간 문자열 상수는 절대 못바꾼다.
    - 그렇다면 Hello를 새로 복사해서 world를 붙이고 str에게 가리키라고 합니다. (Memory Leak)
    - 그러면 기존에 있던 Hello는? : 쓸 수 없다. 정리도 안된다.
  • String toUpperCase("Hello") 이친구는 return을 한다.

  • 출력하는 메서드는 원본을 변경하거나 return을 해줘야 합니다.

  • 알아두면 좋은 메서드 indexOf()

    인덱스를 찾는다면 위치를 알려주지만, 찾지 못했다면 -1 을 출력한다.
    -1 : 큰 수, 내가 끝까지 갔는데 찾지 못했다.
    그래서 indexOf(~~) == -1 이런걸로도 쓴다. 이게 진짜 중요하다.

let company=" minoCNS "
//company_up=String.toUpperCase(company) // 이게 안되네?
company_up=company.toUpperCase();
console.log(company)
console.log(company_up)
console.log(company.indexOf("pa")) // 없으니 -1
//이번엔 모두 대문자로 변경하고 좌우 공백을 제거해야 한다. 
//-> 생각할 것이 좀 있어요 이거
company_trim=company.trim(); // trim을 하고 upper를 해야겠네?
//-> 왜냐 upper할때 공백도 변경할것인가?
company_trimUp=company_trim.toUpperCase();
//이렇게 해도 된다?
company_last=company.trim().toUpperCase();
console.log(company_trimUp.indexOf("MIN"))
//아래 파일 명에서 확장자를 추출해보자.
let filename="mino.hwp"
let file=filename.split('.')
console.log(file[1])

Array 객체

  • 배열 관련된 함수를 가진 객체
  • 배열을 가지고 해 봐야 하는 일
    - 배열의 데이터 개수 파악(length)
    - 배열의 순회(for ~ in), 순회 및 처리(forEach)
    - 배열의 데이터 변환(map)
    - 배열에서 조건에 맞는 데이터를 추출(filter)
    - 배열의 데이터를 정렬(sort)
let ar=[23,39,17,27,44]
// 데이터 개수 파악
console.log(ar.length)
// 데이터 순회
for(idx in ar){
    console.log(ar[idx])
}
// 데이터 순회하면서 작업하기 - forEach // 데이터 처리에 용이하다.
// 배열을 순회하면서 데이터를 하나씩 접근하는 함수
// 첫 번째는 데이터 두번쨰는 인덱스 세번째는 배열
ar.forEach((element, idx, array)=>{
    console.log(array)
})
// 데이터 변환 (map)
// map은 사용하는 형태는 forEach와 동일하지만
// 함수가 데이터를 리턴해야 합니다.
// 리턴한 데이터를 모아서 다시 배열로 만들어서 리턴합니다.
let r=ar.map((element, index, array)=>{
    return element+1
})
console.log(r)
// 데이터 필터링
arr=ar.filter((element, index, array)=>{
   return element%2==1
});
console.log(arr)
let list=[
            {name:"Kim", gender:"남"},
            {name:"Lee", gender:"남"},
            {name:"Park", gender:"여"}
        ]
// gender가 남인 데이터 추출하기
let new_list=list.filter((element, index, array)=>{
    return element.gender==="남";
})
console.log(new_list)
let list=[
            {name:"Park", gender:"남", age:23},
            {name:"Lee", gender:"남", age:19},
            {name:"Kim", gender:"여", age:20}
        ]
let ar=[23,39,167,27,44]
// gender가 남인 데이터 추출하기
let new_list=list.filter((element, index, array)=>{
    return element.gender==="남";
})
console.log(new_list)
// 정렬은 sort 함수를 호출하면 됩니다.
// 기본적으로 오름차순 정렬을 합니다.
// 크기 비교가 가능한 데이터만 정렬을 수행할 수 있습니다.
// sort는 호출한 배열의 데이터를 직접 조작합니다.
ar.sort()
//console.log(ar) //자릿수가 다르면 정렬이 잘 안되는 것을 볼 수 있다.
// why? : JS에서 하는 소트 방식이 뭐길래?
// 직접 크기비교를 하는 방법을 안합니다. 
// 첫번째 글자가 뭐네~ 이러면서 정렬을 하기에 자릿수 문제가 있다.
// 정렬할 때 크기비교 함수를 대입받아서 사용자 정의 정렬을 지원
// 함수의 모양은 매개변수가 2개이고 정수를 리턴해야 합니다.
// 앞의 데이터가 크다고 판단하면, 양수를 리턴하면 됩니다. 관습적으로 1
// 같으면 0 작으면 음수 -1 관습적이야.
ar.sort((left,right)=>{
       return left-right
   }
)// 이 모양은 파이썬에서도 똑같아
// // 정렬을 하려면 크기비교를 할 수 있도록 해야한다.
console.log(ar)
list.sort()
console.log(list) 
// 이건 될것 같아? 객체는 객체끼리 비교 x 속성이 여러개
// 그럼 그 안에 있는 속성끼리 비교해야한다.
list.sort((left,right)=>{
    return left.age-right.age
})
console.log(list)
//문자가 빼기는 안되는데 크기 비교는 할 수 있다.
list.sort((left,right)=>{
    if(left.name>right.name){return 1}
    else if(left.name==right.name){return 0}
    else{return -1}
})
console.log(list) 
// 이렇게 하면 김이박 순으로 나온다. 내림차순을 하려면 부등호 방향 바꾸기
// 우리나라는 자음으로 그룹화 
// -> 가보다 크고 나보다 작은거 : ㄱ으로 시작하는 단어 
alert(navigator.userAgent)
  • Map - Reduce?
    - 병렬로 처리한걸 합병해서 가져오기?
    - 병렬로 한다 : 동시에 한다.(이게 더 빠르겠네)
    • 각각 처리해서 결과를 보겠다.

Sort 정렬

  • 데이터를 순서대로 나열하는 것

  • 오름차순(Ascending - 기본) : 작은 것에서 큰 것 순으로 나열

  • 내림차순(Dscending) : 큰 것에서 작은 것 순으로 나열

  • 다양한 알고리즘을 이용해서 정렬을 수행할 수 있는데,Quick SortMerge Sort 정도는 알고 있으면 면접에 도움이 됩니다.

BOM

  • 브라우저와 관련된 객체
  • window나 navigator 객체를 많이 이용
  • window 객체 안에는 내장 함수와 timer 등이 존재
  • navigator 객체의 userAgent속성에는 접속한 OS와 브라우저를 확인할 수 있는 문자열이 포함되어 있다.
    - 접속한 기기를 확인하고자 할 때, navigator.userAgent를 확인

DOM

  • body에 만든 요소
  • DOM을 가져올 떄는 document.getElementById(아이디)로 찾아옵니다.
<div id="display"></div>
    <input type="text" id="name"/>
    <button id ="btn">버튼</button> 
    <script>
        document.getElementById("btn").addEventListener("click",(e)=>{
            document.getElementById("display").innerHTML=
                document.getElementById("name").value;
        })
</script>

✔ 비동기 처리

동기

  • 순서대로 하나씩 처리

비동기

  • 작업을 수행 주에 다른 작업을 수행할 수 있도록 하는 것

밥짓기와 빨래를 한다고 하자.
동기 : 밥을 다 지을때까지 빨래를 안함
비동기 : 밥을 짓고 남은 시간에 빨래를 하러감

이때, 알람이 없다면 비동기가 어려울 것이다.

ajax(Asynchronous Javascript XML)

  • 비동기적으로 XML을 처리하는 JS
  • (최신!) 비동기적으로 서버의 데이터를 받아서 처리하는 기술

  • 대표적으로 네이버가 많이 쓴다.
  • 실시간으로 바뀌는 데이터를 가져와서 출력을 하는데 다른애의 영향을 안받음
  • 독립적으로 작용중이다.
  • 계속해서 변한다.

✔ HTML5

  • 디자인과 내용의 분리가 메인이다. (디자인은 CSS에게!)
  • 외부 플러그인(Active X, 자바 애플릿, 플래시..)을 최소화 하자
  • HTML5에는 프로그래밍이 들어갑니다.(JS)

새로운 태그들

  • 문서 구조
  • 외부 콘텐츠 삽입 관련
  • 폼 관련
  • 텍스트 관련

추가된 API

  • 브라우저에 데이터를 저장할 수 있게 되었다는 것을 알아두자.
  • 인터넷이 끊어져도 화면에 무엇인가를 볼 수 있다.
  • 핸드폰 mail 앱도 그 예시이다.
  • 모바일의 가장 큰 장점 : Geolocation(위치정보 가져오기)
  • web worker (스레드 사용이 가능한)
  • Server Sent Event (웹은 원래 push가 안된다. 클라가 서버가 요청 안해도 서버가 일방적 데이터 보내는 것)
  • Web socket : 데이터를 주고받는 것이다. HTTP, HTTPS는 계속해서 메시지를 주고받을 수 없는 구조이다. 즉 ajax(HTTP 통신이라 헤더가 너무 무거움)랑은 다른 것이라 생각해야 한다.(overhead 굉장히 작아요 웹소켓은)

참고 : electron 에서 실행파일 만들 때
package.json 수정할 때 mac winodws 맞춰서 설정해주기(주변에 적혀있으니 참고)

profile
밀가루 귀여워요

0개의 댓글