Javascript & jQuery

limprove·2020년 7월 22일
0

자바스크립트

  • 클래스와 오브젝트
  • 객체 생성자 함수
  • 프로토타입
  • 예외처리 (try-catch-finally)
  • 클로저
  • 비동기 처리와 콜백

제이쿼리

  • 비동기 방식 연동(AJAX)
  • 유용한 제이쿼리 플러그인

클래스와 오브젝트

객체 ( object ) ?
서로 연관된 변수와 함수를 그룹핑하고 이름을 붙인 것

const memberObj = {
    manager : 'Kim',
    developer : 'Lee',
    designer : 'Park'
} 

memberObj.designer = 'Lim';
delete memberObj.designer
console.log(memberObj.manager);       // 'Kim'
console.log(memberObj[developer]);    // 'Lee'
console.log(memberObj.desiger);       // undefined

console.group('object loop');
for (let name in memberObj) {
    console.log(name, memberObj.name);    // undefined
    console.log(name, memberObj[name]);    // OK
}
console.groupEnd('object loop');

객체 사용 시 주의할 점 : this

const son = {
    name: 'son',
    first: 10,
    second: 20,
    sum: function(f,s) {
        return f+s;
     // return son.first + son.second
     // return this.first + this.second
    }
}

console.log(son.sum(son.first, son.second));   // 30

객체안에 함수(메소드)가 자신이 속해있는 객체를 가르키는 특수한 키워드를 설정하며, this로 약속한다. this로 인해 객체가 내부적으로 가지고 있는 상태를 함수에서 참조할 수 있다. 하지만 this에 범위는 간혹 예상과 다르게 동작할 수 있다.

자바스크립트에 클래스는 주류 객체지향 언어에서 구현된 클래스 개념을 가져와서 문법적인 거부감 없이 제공하는 일종의 syntactic sugar 이다.

클래스 ( class ) ?

// 클래스 생성자 함수
class Player {
    constructor(name, first, second) {  // 객체의 초기 상태 지정을 위해
    this.name = name;                   // 객체가 만들어지기 직전에 실행되도록 약속된 함수  
    this.first = first;
    this.second = second;    
    }
    sum() {
        return this.first + this.second
    }
}


// 클래스를 생성한 후 프로토 타입 적용? 가능 
Player.prototype.sun = function() {
    return this.first + this.second;
}

const kwon = new Person('kwon', 10, 10);
console.log(kwon);                      // OK
console.log(kwon.sum());                // OK


// 클래스 상속
class PlayerPlus extends Player {
    constructor(name, first, second, third) {
        super(name, first, second);
        this.third = third;
    }
    sum() {
        return super.sum() + this.third;
    }
    avg() {
        return (this.first + this.second + this.third)/3;
    }
}


const lee = new PlayerPlus('lee', 10, 8);
console.log(lee.avg());                // OK

클래스 상속이 필요한 이유?

만약 클래스에 추가적인 기능이 필요한 경우, 클래스가 내가 정의한 것이 아닌, 라이브러리에 경우이거나, 혹은 내가 정의하였어도 프로그램에 전반적으로 사용되는 클래스를 변경하는것이 부담되는 경우 등에 상속을 활용할 수 있다. ( 물론 클래스를 하나 더 추가하여, 복붙하는것도 답이 될수는 있지만 중복이 발생하며, 프로그램이 복잡해진다. 따라서 좋은 방법이 아니다.)

상속을 더욱 활용하는 법? 해답은 super!

super는 두가지 사용법이 있는데, super()는 부모 클래스의 생성자, super.는 부모 클래스 자체이다.

클래스와 객체는 객체지향 프로그래밍을 구성하는 요소이다. 하지만 전통적인 객체지향언어에서의 클래스와 자바스크립트의 클래스/객체는 느낌이 다르다.

//  __proto__ 활용
let superObj = {superVal: 'super'};
let subObj = {subVal: 'sub'}'
subObj.__proto__ = superObj;

console.log(subObj.subVal);       // OK
console.log(subObj.superVal);     // OK
subObj.superVal = 'sub';
console.log(superObj.superVal);   // No, 변화없음


// Object.create() 활용
let subObj = Object.create(superObj);

중요한 사실은, prototype과 __proto__는 명백하게 다른 개념이다.

__proto__는 prototype link로 언제든 상속하는 객체를 변경할 수 있다.
하지만 __proto는 자바스크립트 표준 스펙이 아니므로, Object.create()등의 기능으로 상속할 것을 권장한다.

객체 생성자 함수

앞서 설명한 예시 코드는 어쩌면 가내수공업과 같은 느낌을 준다.
예를 들어 손흥민 객체와 같은 구조에 황희찬 객체를 추가하면, 같은 형식에 변수와 함수를 재정의하게 된다. 이것은 불필요한 작업이며, 메모리 낭비이다.
추가로 전후반이 아닌 연장전 third가 진행되었다면, 우리는 손흥민 객체와 황희찬 객체를 각각 수정해야한다.
이러한 문제를 해결할 수 있는 것, 객체를 공장처럼 찍어낼 수 있는것이 객체 생성자 함수이다.

const son = {
    name: 'son',
    first: 10,
    second: 20,
    sum: function(f,s) {
        return f+s;
     // return son.first + son.second
     // return this.first + this.second
    }
}

const hwang = {
    name: 'hwang',
    first: 10,
    second: 10,
    sum: function(f,s) {
        return this.first + this.second
     // return f+s;
     // return hwang.first + hwang.second
    }
}

console.log(son.sum(son.first, son.second));   // 30
console.log(hwang.sum());                      // 20


// 생성자 함수
function Player() {
    this.name='Park';
    this.first = 20;
    this.second = 20;
    this.sum = function() {
        return this.first + this.second;
    }
}

console.log(Player());       // undefined
console.log(new Player());   // Player { name: 'Park', ...}

// 보통 사용시에는 파라미터를 활용하여 정의한다.
function Player(name, first, second) {
    this.name = name;
    this.first = first;
    this.second = second;
    this.sum = function() {
        return this.first + this.second;
    }
}

예시 코드의 Player()와 같이 함수를 호출하면 일반 함수지만, new Player()와 같이 new 키워드를 사용하면 Player()는 생성자함수가 된다.
[보통 생성자 함수는 구별을 위해 파스칼케이스로 표기한다.]

프로토타입

자바스크립트는 prototype based language 라고 불리기도 했다.
현재(모던 자바스크립트)에서는 중요하게 다루지는 않는데, 그 이유는 ECMA6 이전 자바스크립트에는 클래스라는 개념이 존재하지 않았다. 따라서 클래스가 필요한 상황에 대처하기가 쉽지 않았으며, 클래스 상속을 어느정도 해소하는 기능으로 프로토타입 객체를 활용하였다. 하지만 ECMA6에 자바스크립트에 클래스 개념이 도입되었다. 다른 객체지향 언어의 클래스와는 조금 이질감이 있지만, 자바스크립트에서도 클래스와 상속이 가능하게 되었고, 모던 자바스크립트에서 프로토타입 객체를 활용하는 것은 레거시화 되고 있다.
하지만, 자바스크립트에서 굉장히 중요한 개념이며 기존 프로그램에 상당수는 프로토타입을 활용한 개발이 진행되었기에 프로토타입에 개념과 예시 코드를 자세히 살펴본다.

// 기존 생성자 함수
function Player(name, first, second) {
    this.name = name;
    this.first = first;
    this.second = second;
    this.sum = function() {
        return this.first + this.second;
    }
}

const ki = new Player('ki', 5, 5);    // OK 
const koo = new Player('koo', 5, 5);  // OK

// 프로토타입을 활용한 예시 코드
function Player(name, first, second) {
    this.name = name;
    this.first = first;
    this.second = second;
}

Player.prototype.sum = function() {
    return this.first + this.second;
}

const ki = new Player('ki', 5, 5);    // OK 
const koo = new Player('koo', 5, 5);  // OK

예시 코드에 경우, 생성자 함수를 통해 기성용과 구자철을 생성하였다.
생성한 선수들마다 sum이라는 메소드는 계속적으로 생성되고 있다.
생성자안에서 메소드를 정의하는 것은 유지보수에 측면에서 단점이 있는데, 프로토타입은 해당 생성자가 공통적으로 사용하는 속성 및 함수를 정의할 수 있다.
주로 프로토타입으로 공통적으로 사용하는 속성을 정의하고, 다른 정의가 필요할 때는 해당 인스턴스에 속성 및 메소드를 재정의한다.

프로토타입의 특징은, 해당 객체가 메소드를 호출할 때, 먼저 자신안에 호출 된 메소드를 가지고 있는지 찾는다. 가지고 있다면, 해당 메소드를 호출하고 종료. 가지고 있지 않다면, 자신을 생성한 객체 생성자를 찾아가 해당 생성자의 프로토타입 객체를 찾는다.

예외처리 (try-catch-finally)

클로저

클로저는 함수와 함수가 선언된 어휘적 환경의 조합
함수와 그 함수가 선언될 당시의 환경정보의 조합
함수 내부에서 생성한 데이터와 그 유효범위로 인해 발생하는 특수한 현상

클로저는 함수를 일급 객체로 취급하는 함수형 프로그래밍 언어에서 중요하게 다루는 개념

스코프 -> 함수의 선언 당시 결정 (렉시컬 스코핑)
클로저 -> 반환된 내부 함수가 자신이 선언됐을 때 환경(스코프)를 기억하여 환경 밖에서 호출 되어도 그 환경에 접근할 수 있다.

클로저는 한마디로 최초 선언 시 정보를 유지

이점으로는

  • 접근 권한 제어
  • 지역 변수 보호
  • 데이터 보존 및 활용
function a() {
    var x = 1;
    function b() {
        console.log(x);
    }
    b();
}
a();
console.log(x);


// 데이터 보존 및 활용 -> 변수 은닉
function a() {
    var x = 1;
    return function b() {
        console.log(x);
    }
}
var c = a();
c();

자바 등의 private 기능을 비슷하게 구현하는데 활용

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

비동기 처리와 콜백

비동기 처리는 예전 동기화 챕터를 참조


비동기 방식 연동 (AJAX)

브라우저에서 웹페이지를 요청하거나 링크를 클릭하면 화면 갱신이 발생한다. 이것은 브라우저와 서버와의 통신에 의한 것이다.

Request & Response

서버는 요청받은 페이지(HTML)를 반환하는데 이때 HTML에서 로드하는 CSS나 JavaScript 파일들도 같이 반환된다. 클라이언트의 요청에 따라 서버는 정적인 파일을 반환할 수도 있고 서버 사이드 프로그램이 만들어낸 파일이나 데이터를 반환할 수도 있다. 서버로부터 웹페이지가 반환되면 클라이언트(브라우저)는 이를 렌더링하여 화면에 표시한다.


traditional-webpage-lifecycle

Traditional Web Page Lifecycle

Ajax(Asynchronous JavaScript and XML)는 자바스크립트를 이용해서 비동기적(Asynchronous)으로 서버와 브라우저가 데이터를 교환할 수 있는 통신 방식을 의미한다.

서버로부터 웹페이지가 반환되면 화면 전체를 갱신해야 하는데 페이지 일부만을 갱신하고도 동일한 효과를 볼 수 있도록 하는 것이 Ajax이다. 페이지 전체를 로드하여 렌더링할 필요가 없고 갱신이 필요한 일부만 로드하여 갱신하면 되므로 빠른 퍼포먼스와 부드러운 화면 표시 효과를 기대할 수 있다.

유용한 제이쿼리 플러그인

https://speckyboy.com/free-jquery-plugins/
https://plugins.jquery.com/

profile
즐겁게 개발하는 프론트엔드 개발자 입니다.

0개의 댓글