javaScript/js.this

this

함수 호출 방식 this 바인딩
일반 함수 호출 전역 객체
메소드 호출 메소드를 호출한 객체
생성자 함수 호출 생성자 함수가(미래에) 생성할 인스턴스
Function.prototype.apply/call/bind 메소드에 의한 간접 호출 Function.prototype.apply/call/bind 메소드에 인자로 전달한 객체

바인딩 - 식별자와 값을 연결하는 과정 ex) 변수는 할당에 의해 값이 바인딩된다.

1. this 키워드

동작을 나타내는 메소드는 자신이 속한 객체의 프로퍼티를 참조하고 변경할 수 있어야한다. 이 때 메소드가 자신이 속한 객체의 프로퍼티를 참조하려면 먼저 자신이 속한 객체를 가리키는 식별자를 참조할 수 있어야한다.

  • 생성자 함수 내부에서는 프로퍼티 또는 메소드를 추가하기 위해 자신이 생성할 인스턴스를 참조할 수 있어야 한다.

  • 생성자 함수로 인스턴스를 생성하려면 먼저 생성자 함수가 존재해야 한다.

  • 생성자 함수를 정의하는 시점에서는 아직 인스턴스를 생성하기 이저이므로 생성자 함수가 생성할 인스턴스를 가리키는 식별자를 알 수 없다.

  • 따라서 자신이 속한 객체 또는 자신이 생성할 인스턴스를 가리키는 특수한 식별자가 필요한데 이를 위해 자바스크립트는 this라는 특수한 식별자를 제공한다.

  • this는 자신이 속한 객체 또는 자신이 생성할 인스턴스를 가리키는 자기 참조 변수이다.
    this를 통해 자신이 속한 객체 또는 자신이 생성할 인스턴스의 프로퍼티나 메소드를 참조할 수 있다.

  • 자바스크립트 엔진에 의해 암묵적으로 생성되며 코드 어디에서든지 참조할 수 있다.

  • this가 가리키는 값, 즉 this 바인딩은 함수 호출 방식에 의해 동적으로 결정된다.

javaScript/js.built-in object

빌트인 객체

1. 자바스크립트 객체의 분류

자바스크립트 객체는 크게 3개의 객체로 분류할 수 있다.

  • 표준 빌트인 객체(standard built-in objects, navtive object, global ojbects)

    • ECMAScript 사양에 정의된 객체, 애플리케이션 전역의 공통 기능을 제공
    • 자바스크립트 실행환경과 관계없이 언제나 사용 가능
    • 표준 빌트인 객체는 전역 객체의 프로퍼티로서 제공된다.
    • 별도의 선언없이 전역 변수처럼 언제나 참조할 수 있다.
    • 호스트 객체 (host objects)
    • ECMAScript에 정의되어 있지 않음, 자바스크립트 실행환경에서 추가적으로 제공하는 객체
    • 브라우저 환경에서는 클라이언트 사이드 Web API를 호스트 객체로 제공
    • Node.js 환경에서는 Node.js 고유의 API를 호스트 객체로 제공
  • 사용자 정의 객체 (user-defined objects)

    • 기본으로 제공되는 객체가 아닌 사용자가 직접 정의한 객체

javaScript/js.strictMode

엄격모드

1. strict mode

ES5부터 strict mode가 추가되었다.
자바스크립트 언어의 문법을 보다 엄격히 적용하여 기존에 무시되던 오류를 발생시킬 가능성이 높거나 자바스크립트 엔진의 최적화 작업에 문제를 일으킬 수 있는 코드에 대해 명시적 에러를 발생시킨다.

ESlint같은 도구로 비슷한 효과를 얻을 수 있다.
린트는 정적분석 기능을 통해 소스코드를 실행하기 전에 소스 코드를 스캔하여 문법적 오류만이 아니라 잠재적 오류까지 찾아내고 오류의 이유도 리포팅 해준다.

2. strict mode의 적용

  • strict mode를 적용하려면 전역의 선두 또는 함수 몸체 선두에 ‘use strict’;를 추가
    전역 선두에 추가하면 스크립트 전체에 적용된다.

  • 함수 몸체의 선두에 추가하면 해당 함수와 중첩된 내부 함수에 strict mode 적용

  • 코드의 선두에 strict mode를 위치시키지 않으면 작동하지않는다 (에러발생시키지않음)

javaScript/js.ProtoType2

프로토타입(2)

10. 프로토타입의 교체

프로토타입은 다른 임의의 객체로 변경할 수 있다. (부모 객체인 프로토타입을 동적으로 변경할 수 있다는 것을 의미)
이러한 특징을 기반으로 객체 간의 상속 관계를 동적으로 변경할 수 있다.
프로토타입은 생성자 함수 또는 인스턴스에 의해 교체할 수 있다.

10.1 생성자 함수에 의한 프로토타입의 교체

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
const Person = (function () {
function Person(name) {
this.name = name;
}

//@생성자 함수의 prototype 프로퍼티를 통해 프로토타입을 교체
//Person 생성자 함수가 생성할 객체의 프로토타입을 객체리터럴로 교체
Person.prototype = {
sayHello() {
console.log(`Hi! My name is ${this.name}`);
}
};
return Person;
}());
const me = new Person('jung');

javaScript/js.ProtoType1

프로토타입(1)

1. 객체지향 프로그래밍 (OPP, Object Oriented Programming)

  • 객체들의 집합으로 프로그램을 표현하려는 프로그래밍 패러다임
  • 상태 데이터와 동작을 하나의 논리적 단위로 묶음 복합적인 자료구조
  • 객체의 상태 데이터 - 프로퍼티(property), 동작 - 메소드(method)
  • 각각의 객체는 자신의 고유한 기능을 수행하면서 다른 객체와 관계성을 갖을 수 있다.

2. 상속과 프로토타입

  • 객체의 프로퍼티 또는 메소드를 다른 객체가 상속받아 그대로 사용할 수 있다.
  • 프로토타입을 기반으로 상속을 구현하여 불필요한 중복을 제거한다.
  • 동일한 생성자 함수에 의해 생성된 모든 인스턴스가 동일한 메소드를 중복 소유하는 것은 메모리를 불필요하게 낭비한다. -> 인스턴스를 생성할 때마다 메소드를 생성하므로 퍼포먼스에도 악영향을 준다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
//생성자 함수
function Circle(radius) {
this.radius = radius;
}
//Circle 생성자 함수가 생성한 모든 인스턴스가 공유할 수 있도록 getArea 메소드를 프로토 타입에 추가한다.
// 프로토타입은 Circle 생성자 함수의 prototype 프로퍼티에 바인딩되어있다.
Circle.prototype.getArea = funciton = () {
return Math.PI * MAth.pow(this.radius, 2);
};

//인스턴스 생성
const circle1 = new Circle(1);
const circle2 = new Circle(2);

//Circle 생성자 함수가 생성한 모든 인스턴스는 부모 객체의 역할을 하는 프로토타입
//Circle.prototype로부터 getArea 메소드를 상속받는다.
//즉, Circle 생성자 함수가 생성하는 모든 인스턴스는 하나의 getArea 메소드를 공유한다.
console.log(circle1.getArea === circle2.getArea); // true
console.log(circle1.getArea()); // 3.14~
console.log(circle2.getArea()); // 12.56~

javaScript/js.firstClassObject

함수와 일급 객체

1. 일급 객체 (first-class object)

  1. 무명의 리터럴로 생성할 수 있다. (런타임에 생성 가능)
  2. 변수나 자료 구조(객체, 배열 등)에 저장할 수 있다.
  3. 함수의 매개 변수에 전달할 수 있다.
  4. 함수의 결과값으로 반환할 수 있다.

함수는 === 일급객체

  • 일급객체인 함수는 객체와 동일하게 사용할 수 있다. 객체 = 값, 함수 = 값
  • 함수는 값을 사용할 수 있는 곳 어디서든지 리터럴로 정의할 수 있으며, 런타임에
    함수 객체로 평가 된다.
  • 고유 프로퍼티를 갖는 것, 호출할 수 있는 것을 제외하면 일반객체와 동일하다.
  • 일반 객체처럼 함수의 매개 변수에 전달할 수 있으며 함수의 결과값으로 반환할 수 있다. (고차함수)
  • 고유 프로퍼티(데이터) (arguments, caller, length, name, prototype)

2. 함수 객체의 프로퍼티

2.1 arguments 프로퍼티

  • 함수 객체의 arguments 프로퍼티 값은 arguments 객체
  • 함수 호출시 전달된 인수(argument)들의 정보를 담고 있는 순회 가능한(iterable) 유사 배열 객체(array-like object)이며 함수 내부에서 지역 변수처럼 사용된다.
  • 외부에서는 사용 불가
  • 함수 호출시 함수 정의에 따라 인수를 전달하지 않아도 에러가 발생하지 않는다.
  • 함수가 호출되면 함수 몸체 내에서 암묵적으로 매개변수가 선언되고, undefined로 초기화된 이후 인수가 할당된다.

javaScript/js.constructor

생성자 함수에 의한 객체 생성

1. Object 생성자 함수

  • new 연산자와 함께 Object 생성자 함수를 호출하면 빈 객체를 생성하여 반환한다.
  • 생성자(constructor) 함수란 new 연산자와 함께 호출하여 객체(인스턴스)를 생성하는 함수를 말한다. 생성자 함수에 의해 생성된 객체를 인스턴스(instance)라 한다.
  • new 연산자와 함께 생성자 함수를 호출하지 않으면, 일반 함수로 동작한다.

2. 생성자 함수

2.1 객체 리터럴에 의한 객체 생성 방식의 문제점

  • 객체 리터럴에 의한 객체 생성 방식은 단 하나의 객체만을 생성한다.
  • 동일한 프로퍼티를 갖는 객체를 여러개 생성해야 하는 경우 비효율적이다.
  • 객체는 프로퍼티를 통해 객체의 고유상태를 표현,
    메소드를 통해 상태 데이터인 프로퍼티를 참조하고 조작하는 동작을 표현한다.

2.2 생성자 함수에 의한 객체 생성 방식의 장점

  • 프로퍼티 구조가 동일한 객체 여러 개를 간편하게 생성한다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
// 생성자 함수

function Circle(radius) {
this.radius = radius;
this.getDiameter = function () {
return 2 * this.radius;
};
}
// 인스턴스의 생성

const circle1 = new Circle(5); //반지름이 5인 Circle 객체 생성
const circle2 = new Circle(10); //반지름이 10인 Circle 객체 생성

console.log(circle1.getDiameter()); // 10
console.log(circle2.getDiameter()); // 20

javaScript/js.property

프로퍼티 어트리뷰트

1. 내부 슬롯과 내부 메소드

  • 내부 슬롯과 내부 메소드는 자바스크립트 엔진의 알고리즘을 설명하기 위해 ECMA 사양에서 사용하는 의사 프로퍼티와 의사 메소드 이다. [[]]
  • 외부로 공개된 객체의 프로퍼티는 아니다.
  • 간접적으로만 접근할 수 있다.

2. 프로퍼티 어트리뷰트와 프로퍼티 디스크립터 객체

자바스크립트 엔진은 프로퍼티를 생성할 때, 프로퍼티의 상태를 나타내는 프로퍼티 어트리뷰트를 기본값으로 자동 정의

프로퍼티 상태?
프로퍼티의 값(value), 값의 갱신 가능여부(writable), 열거가능여부(enumberable), 재정의 가능여부(configurable)

프로퍼티 어트리뷰트

  • 자바스크립트 엔진이 관리하는 내부 상태 값(meta-property)
  • Object.getOwnPropertyDescriptor 메소드를 이용해 간접적으로 확인할 수 있다. (직접적 불가)
    • 메소드를 호출할 때, 첫번째 매개변수에는 객체의 참조를 전달
      두번째 매개변수에는 프로퍼티 키를 문자열로 전달한다.
    • 프로퍼티 어트리뷰트 정보를 제공하는 프로퍼티 디스크립터(PropertyDescriptor)객체를 반환
    • 만약 존재하지 않는 프로퍼티, 상속받은 프로퍼티에 대한 프로퍼티 디스크립터를 요구하면 undifined가 반환
    • ES8에 도입된 Object.getOwnPropertyDescriptors 메소드는 모든 프로퍼티의 프로퍼티 어트리뷰트 정보를 제공하는 프로퍼티 디스크립터 객체들을 반환

javaScript/js.let const and var

let, const와 블록 레벨 스코프 (feat. var)

1. var로 선안한 변수의 문제점

1.1 변수 중복 선언 허용

  • 같은 스코프 내에서 변수를 중복 선언하면 나중에 작성된 변수 선언문은 자바 스크립트 엔진에 의해 var 키워드가 없는 것 처럼 동작한다.
  • 먼저 선언된 변수값이 변경되는 부작용 발생
  • 문법적으로 허용, 하지만 사용하지 않는 것이 좋다.

1.2 함수 레벨 스코프

  • 오직 함수 코드블록만을 지역 스코프로 인정한다.
  • 함수 외부에서 var 키워드 선언 -> 전역 변수(코드 블록 내에 있더라도 for문 등등..)

1.3 변수 호이스팅

  • 변수 선언문이 스코프의 선두로 끌어 올려진 것처럼 동작한다.
  • 변수 선언문 이전에 변수를 참조하는 것은 변수 호이스팅에 의해 에러를 발생시키지는 않지만 가독성을 떨어뜨리고 오류를 발생시킬 가능성이 있다.

javaScript/js.global variable

전역 변수의 문제점

전역 변수의 무분별한 사용은 위험하다. 반드시 사용해야 할 이유를 찾지 못한다면 지역 변수를 사용해야한다.

1. 변수의 생명 주기

변수는 선언에 의해 생성되고 할당을 통해 값을 갖는다.
생명주기(Life cycle)이 있다.

1.1 지역 변수의 생명 주기

지역 변수는 함수가 호출되면 생성되고 함수가 종료하면 소멸한다.

1
2
3
4
5
function foo() {
var x = 'local';
console.log(x);
return x;
}

지역 변수 x는 변수가 호출되기 이전까지는 생성되지 않는다.

  • 함수 내부에서 선언한 변수는 함수가 호출된 직후, 함수 몸체의 다른 코드가 실행되기 전에 자바스크립트에 의해 실행되고 undefined로 초기화된다.
  • 그 후, 함수 몸체의 문들이 순차적으로 실행되고 변수 할당문이 실행되면 변수에 값이 할당된다.
  • 함수가 종료하면 지역 변수도 소멸되어 생명 주기가 종료된다.
  • 지역 변수 생명주기 == 함수 생명 주기
Your browser is out-of-date!

Update your browser to view this website correctly. Update my browser now

×