gmlwjd9405 / gmlwjd9405.github.io

:seedling: Heee's Development Blog
MIT License
79 stars 33 forks source link

미완성글 저장하기 #2

Open gmlwjd9405 opened 5 years ago

gmlwjd9405 commented 5 years ago

변수 선언 방식 반복문과 조건문 데이터 타입별 기본적인 메소드들 형변환 및 연산자, 표현식 등


화살표 표기법

함수스코프, 실행컨텍스트

스코프: 유효범위(변수)

실행 컨텍스트: 실행되는 코드덩어리(추상적 개념)

var a = 1;
function outer() {
  console.log(a); // 1. 1

  function inner() { 
    console.log(a); // 2. undefined
    var a = 3;
  }
  inner();
  console.log(a); // 3. 1
}
outer();
console.log(a); // 4. 1

메소드

콜백함수

// 같은 동작을 하도록 직접 구현 Array.prototype.forEach = function(callback, thisArg) { var self = thisArg || this; // thisArg가 없으면 Array의 인스턴스 for(var i = 0; i < this.length; i++) { callback.call(self, this[i], i, this); // this 바인딩의 핵심. value, index, array } // callback에 어떤 데이터를 매개변수로 넘겨줄지 정해져 있다. }

```js
var arr = [1, 2, 3, 4, 5];
var entried = [];
arr.forEach(function(v, i) {
    entries.push([i, v, this[i]]);
}, [10, 20, 30, 40, 50]);

console.log(entries);

$('#a').on('click', cbFunc); // JQuery

  - 예상: this는 바인딩한 것이 없으니 global 객체, x로는 넘긴 것이 없다.
  - 결과: `<div id="a">abc</div> => MouseEvent {isTrusted: true, screenX: 11, ...`
  - addEventListener의 규칙과 다르게 콜백함을수를 정의했기 때문에 this와 x 모두 잘못 출력되었다.
  - 규칙 => 첫 번째 인자: 이벤트 객체, 두 번째 인자: 이벤트 타겟 

```js
// MDN 정의
target.addEventListener(type, listener[, useCapture]);
/*
type: 등록할 event type을 나타내는 문자열
listener: 특정 타입의 이벤트가 발생할 때 알림을 받을 객체. 
*/
var arr = [1, 2, 3, 4, 5];
var obj = {
  vals: [1, 2, 3],
  logValues: function(v, i) {
    if(this.vals) {
      console.log(this.vals, v, i);
    } else {
      console.log(this, v, i);
    }
  }
};
obj.logValues(1, 2); // 1. 
arr.forEach(obj.logValues); // 2.  
  1. obj.logValues(1, 2);
    • 메소드로 호출. 즉, this가 obj가 된다.
    • if(this.vals)가 참이므로, 아래 log가 출력된다.
    • 결과: {_vals: Array{3}, logValues: f} 1 2
  2. arr.forEach(obj.logValues);
    • 콜백함수로 전달. 즉, obj.logValues가 가리키는 참조가 넘어간다.
    • this가 forEach의 규칙을 따른다.
    • this가 바인딩되지 않았기 때문에 Window가 출력된다.
    • 결과: Window {stop: f, open: f, alert: f, confirm: f, prompt: f, ...} 1 0

this 키워드

  1. 전역공간에서: 전역 객체. window/global: 전역 객체의 구현체
    • 브라우저 콘솔에서 console.log(this);는 window
    • node.js에서 console.log(this);는 global
  2. 함수 내부에서: 전역 객체. window/global
    • default가 전역 객체
    • 변경될 수 있다.
  3. 메소드 호출시
    • 메소드를 호출한 주체 (메소드명 앞)
      // Ex 1) a객체 
      var a = {
      b: function() {
      console.log(this);
      }
      }
      a.b();
      // Ex 2) a.b객체
      var a = {
      b: {
      c: function() {
      console.log(this);
      }
      }
      }
      a.b.c();
  1. callback에서

    • 기본적으로는 함수내부에서와 동일
    • 제어권을 가진 함수가 callback의 this를 명시한 경우 그에 따른다.
    • 개발자가 this를 바인딩한 채로 callback을 넘기면 그에 따른다.
      
      var callback = function() {
      console.dir(this); 
      };
      var obj = {
      a: 1, 
      b: function(cb) {
      cb(); // 결과: window

    cb.call(this); // 결과: Object i a: 1 b: function(cb)... // 제어권을 넘겨받은 함수나 메서드가 this를 다른 것으로 명시하면, 다른 객체 출력 } }; obj.b(callback);

    
    ```js
    var callback = function() {
    console.dir(this); 
    };
    var obj = {
    a: 1 
    };

setTimeout(callback, 100); // 결과: window

setTimeout(callback.bind(obj), 100); // 결과: Object


5. 생성자 함수에서
- 인스턴스
```js
function Person(n, a) {
  this.name = n;
  this.age = a;
}
var gomugom = new Person('고무곰', 30);
console.log(gomugom) 

call, apply, bind

a.call(b, 1, 2, 3);

a.apply(b, [1, 2, 3]);

var c = a.bind(b); c(1, 2, 3);

var d = a.bind(b, 1, 2); d(3);

  - 모두 출력 결과는 `Object {c: "eee"} 1 2 3`으로 동일 
  - call
    - 
  - apply
    - call과 동일
    - 배열 요소를 함수 매개변수로 사용해야 할 때 유용
  - bind
    - 함수의 this 값을 영구적으로 바꿀 수 있다.
    - bind는 함수의 동작을 영구적으로 바꾸기때문에 찾기 어려운 버그의 원인이 될 수 있다.
    - bind는 매우 유용하지만, 함수의 this가 어디에 묶이는지 정확히 하악하고 사용해야 한다.
    - 

## 클로저
### 클로저
 ```code
A closer is the combination of a function 
and the lexical environment(사전적 환경) which that function was declared.
=> 함수와 함수가 선언된 어휘적 환경의 조합이다.??

선언 당시의 환경에 대한 정보를 담은 객체 (구성 환경)

  1. 접근 권한 제어

    function a() {
    var x = 1;
    function b() {
     console.log(x);
    }
    b();
    }
    a();
    console.log(x);
    • x에 대한 접근 권한은 function a와 b 내부에서는 가능
    • 그 외부에서는 불가능
  2. 지역변수 보호

  3. 데이터 보존 및 활용

    function a() {
    var x = 1;
    return function b() {
     console.log(x);
    }
    }
    var c = a();
    c(); // x의 값을 출력. 하지만 변경은 불가.
    • 외부에 권한 부여
    • getter, setter를 이용
    • _x는 외부에 전혀 노출되어 있지 않다.
    function a() {
    var _x = 1;
    return function b() {
     get x() { return _x; },
     set x(v) { _x = v; }
    }
    }
    var c = a();
    c.x = 10; // 외부에서 x 프로퍼티 변경 가능.

지역변수 만들기

  1. 함수에서 지역변수 및 내부함수 등을 생성한다.
  2. 외부에 노출시키고자 하는 멤버들로 구성된 객체를 return한다.
    • return한 객체에 포함되지 않은 멤버들은 private하다.
    • return한 객체에 포함된 멤버들은 public하다.

prototype

prototype과 constructor, proto

메소드 상속 및 동작 원리

 function Person(n, a) {
   this.name = n;
   this.age = a;
 }

 var gomu = new Person('고무곰', 30);
 var iu = new Persion('아이유', 25);

 gomu.setOlder = function() {
   this.age += 1;
 }
 gomu.getAge = function() {
   return this.age;
 }
 iu.setOlder = function() {
   this.age += 1;
 }
 iu.getOlder = function() {
   return this.age;
 }
 function Person(n, a) {
   this.name = n;
   this.age = a;
 }
 Person.prototype.setOlder = function() {
   this.age += 1;
 }
 Person.prototype.getAge = function() {
   return this.age;
 }
 var gomu = new Person('고무곰', 30);
 var iu = new Persion('아이유', 25);
 gomu.__proto__.setOlder();
 gomu.__proto__.getAge(); // NaN

 gomu.setOlder(); // __proto__가 생략이 가능하므로, this는 gomu를 가리킨다.
 gomu.getAge(); // 31
 Person.prototype.age = 100;
 gomu.__proto__.setOlder();
 gomu.__proto__.getAge(); // 101

 gomu.setOlder(); 
 gomu.getAge(); // 31

prototype chaining

사각지대

Class

prototype static 메서드 및 static 프로퍼티

class 상속 구현

References

gmlwjd9405 commented 5 years ago

layout: post title: '[JavaScript] 화살표 함수(Arrow Function)의 개념과 사용법' subtitle: '자바스크립트의 화살표 함수(Arrow Function)에 대해 이해한다.' date: 2019-04-26 author: heejeong Kwon cover: '/images/javascript/javascript-main.png' tags: javascript function comments: true sitemap : changefreq : daily priority : 1.0

Edwith 강의 참고

Goal

  • 자바스크립트의 선언 방식변수의 종류를 확인한다.
    • var과 let, const의 차이에 대해 이해한다.
  • 자바스크립트의 연산자의 종류 및 개념을 이해한다.
  • 자바스크립트의 타입의 종류를 확인한다.
    • 자바스크립트에서 type 체크 방법에 대해 이해한다.
    • 자바스크립트에서 null 체크 방법에 대해 이해한다.

화살표 함수 (Arrow Function, Fat Arrow)

화살표 함수(Arrow Function) 이란

materials.map(function(material) { // 익명 함수 return material.length; }); // [8, 6, 7, 9]

materials.map((material) => { // function 생략 return material.length; }); // [8, 6, 7, 9]

materials.map(({length}) => length); // return 및 {} 생략 // [8, 6, 7, 9]


### 화살표 함수의 특징
- 화살표 함수는 항상 익명이다.

- 매개변수가 하나인 경우 괄호는 선택사항이다. 하지만 매개변수가 없는 경우엔 반드시 괄호를 적어야 한다.
```js
// 매개변수가 하나뿐인 경우 괄호는 선택사항
(singleParam) => { statements }
singleParam => { statements }

// 매개변수가 없는 함수는 괄호가 필요
() => { statements }
// ES5 익명 함수표현식 (function expression)
var sum = function(a, b) {
    return a + b;
};

// ES6 화살표 함수 이용 
var sum = (a, b) => {
    return a + b;
}
sum (10, 20);
// ES5 함수선언문 (function declaration)
function getName(name) {
   return "Kim " + name ;
}

// ES6 화살표 함수 이용 
var getName = (name) => "Kim " + name;
var getName = name => "Kim " + name;
var arr = ["a", "b", "c"];

// ES5
arr.forEach(function(value){ // 익명 함수
    console.log(value); // a, b, c
});
// ES6 화살표 함수 이용
arr.forEach(value => console.log(value)); // a, b, c

향상된 객체 리터럴 (Enhanced Object Literals)

관련된 Post

Reference

gmlwjd9405 commented 5 years ago

0(숫자): 라인 맨 앞으로 커서 이동 관련 포스트 추가 vim 연습 도구 추가 [ctrl + v]: 사각형의 블럭지정이 가능하다. 기능 확인 후 (멀티 포커스로 이름 변경) 오른쪽으로 tabn , tabnext gt 왼쪽으로 tabp , :tabprevious gT

정렬 수정 캡처 다시 확인 화살표 변경 단어 단위로 여러 줄 선택 링크 확인 참고 Debugger 탭 설명 위치 변경 단축키 내용 Bold 처리

gmlwjd9405 commented 5 years ago

@SpringBootApplication is a convenience annotation that adds all of the following:

@Configuration tags the class as a source of bean definitions for the application context.

@EnableAutoConfiguration tells Spring Boot to start adding beans based on classpath settings, other beans, and various property settings. For example, if spring-webmvc is on the classpath this flags the application as a web application and activates key behaviors such as setting up a DispatcherServlet.

@ComponentScan tells Spring to look for other components, configurations, and services in the hello package, allowing it to find the controllers.

gmlwjd9405 commented 5 years ago

양방향 매핑 시 가장 많이 하는 실수

연관관계의 주인에 값을 입력하지 않는다.

Member member = new Member();
member.setName("member1");
em.persist(member);

Team team = new Team();
team.setName("TeamA");
team.getMembers().add(member); // 역방향(주인이 아닌 방향)에만 연관관계 설정
em.persist(team);
Member member = new Member();
member.setName("member1");
em.persist(member);

Team team = new Team();
team.setName("TeamA");
em.persist(team);

// team.getMembers().add(member); // 역방향(주인이 아닌 방향)에만 연관관계 설정
member.setTeam(team); // 주인에 연관관계를 설정해야 함

양방향 매핑 시 주의할 점

1. 순수 객체 상태를 고려해서 항상 양쪽에 값을 설정하자.

Team team = new Team();
team.setName("TeamA");
em.persist(team);

Member member = new Member();
member.setName("member1");
em.persist(member);

member.setTeam(team); //** 연관관계의 주인에 값 설정

// 이 설정 없이도 "지연 로딩"을 통해서 아래에서 findTeam.getMembers에 접근 가능
// team.getMembers().add(member); //** 역방향에 연관관계 설정

// --- TEAM_ID(FK)가 설정되어 있지 않은 Member가 1차 캐시에만 영속화된 상태
em.flush();
em.clear();
// --- DB에 TEAM_ID(FK) 설정된 상태 

Team findTeam = em.find(Team.class, team.getId());
List<Member> findMembers = findTeam.getMembers();

// team.getMembers().add(member); 을 하지 않아도 조회 가능 (지연 로딩)
for (Member findMember : findMembers) {
    System.out.println("findMember = " + findMember.getName()); 
}

tx.commit();

동작 설명

  1. flush(), clear()
    • 1차 캐시를 지우기 때문에 DB에서 다시 조회하게 된다.
    • 이 동작을 하는 순간에 DB에 TEAM_ID(FK)가 세팅된다.
    • 즉, 이 동작이 일어나지 않으면 DB에 TEAM_ID(FK)가 설정되는 Query가 날라가지 않는다는 것이다.
    • 위의 동작을 수행하기 전에 findTeam.getMembers()를 하게 되면 해당 List의 size = 0 이다.
    • 왜냐하면, TEAM_ID(FK)가 설정되지 않은 Member가 1차 캐시에만 영속화 되어있는 상태이기 때문이다.
  2. findTeam.getMembers()
    • FK가 세팅되었기 때문에 이후에 지연 로딩을 통해서 JOIN Query로 조회할 수 있다.
    • 지연 로딩: 실제 findMembers를 로딩했을 때 쿼리가 나간다.

주인에만 값을 설정했을 때의 문제점 (2가지)

Team team = new Team();
team.setName("TeamA");
em.persist(team);

Member member = new Member();
member.setName("member1");
em.persist(member);

member.setTeam(team); //** 연관관계의 주인에 값 설정
// team.getMembers().add(member); //** 역방향에 연관관계 설정

// 1. flush와 clear가 없는 경우 
// em.flush();
// em.clear();

Team findTeam = em.find(Team.class, team.getId()); // 1차 캐시 
List<Member> findMembers = findTeam.getMembers();

for (Member findMember : findMembers) {
    System.out.println("findMember = " + findMember.getName()); // size = 0
}

tx.commit();
  1. flush, clear가 없는 경우 (이 동작없이 주인에만 값을 설정한 경우)
    • List에 연관관계를 설정하지 않은 상태의 Team이 영속성 컨텍스트에 들어간다.
    • 이런 형태의 Team이 메모리(1차 캐시)에만 올라가 있게 된다.
    • 즉, em.find(Team.class, team.getId())에서의 값은 SELECT Query를 통해서 가져오는 것이 아니다.
  2. Test Case를 작성하는 경우
    • JPA 없이 순수 자바 Object로 테스트 케이스가 동작하게끔 테스트 코드를 작성할 때 NPE이 발생한다.

2. 연관관계 편의 메서드를 생성하자.

class Member {
    ...

    public void changeTeam(Team team) {
        this.team = team;
        team.getMembers().add(this); // 나 자신의 instance를 넣는다. 
    }
}
class Team {
    ...

    public void addMember(Member member) {
        member.setTeam(this); // 나 자신의 instance를 넣는다. 
        members.add(member);
    }
}

3. 양방향 매핑 시 무한 루프를 주의하자.

lombok이 자동으로 만드는 toString()을 사용하지 말자.

// Member의 toString()
@Override
  public String toString() {
      return "Member{" +
          "id=" + id +
          ", username='" + username + '\'' +
          ", team=" + team +
          '}';
  }
// Team의 toString()
@Override
    public String toString() {
        return "Team{" +
            "id=" + id +
            ", name='" + name + '\'' +
            ", members=" + members +
            '}';
    }

JSON 생성 라이브러리 사용 시 주의하자.


양방향 매핑 정리

gmlwjd9405 commented 5 years ago

다양한 연관관계 매핑

Goals

  • 연관관계 매핑시 고려사항 3가지
  • 다대일 [N:1]
  • 일대다 [1:N]
  • 일대일 [1:1]
  • 다대다 [N:M]

연관관계 매핑시 고려사항 3가지

1. 다중성

2. 단방향, 양방향

3. 연관관계의 주인


다대일 [N:1]

다대일 단방향 관계 매핑

public class Member {
  ...
  @ManyToOne
  @JoinColumn(name = "TEAM_ID")
  private Team team;
  ...
}

다대일 양방향 관계 매핑

코드 예시

public class Team {
    ...
    @OneToMany(mappedBy = "team") // Member Entity의 team 필드에 의해 매핑되어 짐
    private List<Member> members = new ArrayList<>();
    ...
}

일대다 [1:N]

일대다 단방향 관계 매핑

코드 예시

@Entity
public class Team {
    ...
    @OneToMany
    @JoinColumn(name = "TEAM_ID")
    private List<Member> members = new ArrayList<>();
    ...
}
// Main.java
...
Member member = new Member();
member.setName("member1");
em.persist(member);

Team team = new Team();
team.setName("teamA");
team.getMembers().add(member); 
em.persist(team);

tx.commit();

쿼리 확인

Hibernate: 
    /* insert hellojpa.Member */ 
    insert 
        into
            Member
            (id, age, createdDate, description, lastModifiedDate, roleType, name) 
        values
            (null, ?, ?, ?, ?, ?, ?)
Hibernate: 
    /* insert hellojpa.Team */
    insert 
        into
            Team
            (id, name) 
        values
            (null, ?)
/* Member Table에 대한 업데이트 쿼리가 수행되는 것을 확인할 수 있다. */
Hibernate: 
    /* create one-to-many row hellojpa.Team.members */ 
    update
        Member 
    set
        TEAM_ID=? 
    where
        id=?

일대다 단방향의 문제점

일대다 양방향 관계 매핑

@Entity
public class Member {
  ...
  @ManyToOne
  @JoinColumn(name = "TEAM_ID", insertable = false, updatable = false)
  private Team team;
  ...
}
gmlwjd9405 commented 5 years ago

상속 관계 매핑이란

데이터베이스의 Super-Sub 타입 "논리" 모델을 실제 "물리" 모델로 구현하는 방법

주요 어노테이션

객체의 상속관계 구현 예시

/** Item Class */ 
@Entity
@Inheritance(strategy = InheritanceType.XXX) // 상속 구현 전략 선택
public class Item {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    private String name;
    private int price;
}
/** Album Class */ 
@Entity
public class Album extends Item {

    private String artist;
}
/** Movie Class */ 
@Entity
public class Movie extends Item {

    private String director;
    private String actor;
}
/** Book Class */ 
@Entity
public class Book extends Item {

    private String author;
    private String isbn;
}

1. JOINED - 조인 전략

2. SINGLE_TABLE - 단일 테이블 전략

3. TABLE_PER_CLASS - 구현 클래스마다 테이블 전략

정리

상속 관계 매핑 방법 (세 가지) 정리