Inside Javascript 정리 - 1 (데이터타입, 함수)

Chapter 03 자바스크립트 데이터 타입과 연산자

자바스크립트 데이터 타입

  • 기본 타입 - Number, String, Boolean, undefined, null
  • 참조 타입 - Object (Array, Function, 정규표현식)

자바스크립트 기본 타입

: 느슨한 타입 체크 언어로 변수를 선언할 때 타입을 미리 정하지 않고 , var이라는 한가지 키워드로만 변수를 선언해. 여기에는 어떤 데이터라도 저장하는 것이 가능한거지.

즉, 자바스크립트는 변수에 어떤 형태의 데이터를 저장하느냐에 따라 해당 변수의 타입이 결정되


Number

: 자바스크립트는 정수형이 따로 없고, 모든 숫자를 실수로 처리.

( 그렇기에 나눗셈 연산에서 c랑 다른 결과값이 나오기에 주의)


문자열

: “ 혹은 ‘ 로 정의하는데 중요한것은 정의된 문자열은 변하지 않아!

즉 자바스크립트에서는 한 번 생성된 문자열은 읽기만 가능하고 수정 불가


null vs undefined

: 이 두 타입 모두 자바스크립트에서 값이 비어있음을 나타내.

자바스크립트 환경 내에서 기본적으로 값이 할당되지 않은 변수는 undefined 타입이며 값 또한 undefined이야.

null 타입 변수의 경우는 개발자가 명시적으로 값이 비어있음을 나타내는 데 사용해.

참고로 null은 Object 타입이기에 비교할 때 typeof가 아닌 일치연산자(===)를 사용해야해.


자바스크립트 참조타입

: 자바스크립트에서는 기본타입을 제외한 모든 값은 객체야. 자바스크립트에서 객체란 ‘key : value’ 형태의 프로퍼티들을 저장하는 컨테이너라고 생각하면 돼.

기본타입은 하나의 값만 가지지만 참조타입인 객체는 여러 개의 프로퍼티들을 포함할 수 있고 또 이러한 객체의 프로퍼티는 기본타입의 값을 포함하거나, 다른 객체를 가리킬 수도 있어.


객체 생성

  1. 자바스크립트 내장되어 기본제공되는 Obeject() 객체 생성자 함수 이용

  2. 객체 리터럴 ( {}이용 )

  3. 생성자 함수


객체 property 읽기/쓰기/갱신

접근 방법에는 크게 두가지가 있어.

  1. 대괄호( [ ] ) 표기법

  2. 마침표 ( . ) 표기법

편한거 사용하면 되긴 하지만 주의할 점이 property가 ‘full-name’ 이런 형태라면 마침표 표기법을 이용하면 - 연산이 일어날 수도 있기에 이럴 경우 대괄호 표기법을 사용해야해.


for in

: for in 문을 이용하면 객체의 모든 property에 순차적으로 접근할 수 있어.

자바스크립트에서는 배열도 객체로 구분하는데 이 때 배열 내부의 값만 접근하고프다면

for in 보다는 length를 이용한 for문이 좋아! (배열의 출력을 원하지않는 프로퍼티가 출력될수도..)


객체 비교

: 동등 연산자 (==)를 사용하여 두 객체를 비교할 때도 객체의 프로퍼티 값이 아닌 참조값을 비교해!!

→ 값이 동일하더라도 참조하는 녀석이 다르다면 false를 반환하게 되는거지!


참조에 의한 함수 호출 방식

  • 기본 타입 : Call by value

  • 참조 타입 : Call by reference


프로토타입

(처음 알게된 내용이니까 자세히 보자!!)

자바스크트의 모든 객체는 자신의 부모 역할을 하는 객체와 연결되어있어. 그래서 이를 이용해 상속 개념처럼 사용할 수 있게 되는거지.

이런 부모 객체를 자바스크립트에서는 프로토타입 객체라고 불러.

자바스크립트의 모든 객체는 자신의 프로토타입을 가리키는 숨겨진 property를 가지고 있어.

객체.toString() 같은 메소드를 이용할 수 있는 것도 다 그런 이유에서 가능한거야!


배열 length property

: length property는 배열의 원소 개수를 나타냈으나 꼭 배열에 존재하는 원소개수와 일치하는 것은 아니야. undefined로 값이 존재하지 않아도 length property에는 count 되는거지.

→ 배열의 사이즈는 length property+1이 된다 생각하면 돼.

그렇기에 기존에 명시 해 놓은 배열 사이즈보다 더 적게 length를 변경시킨다면 배열의 뒷부분이 삭제될 수도 있어.


배열과 객체

이 둘 모두 Object이나 차이가 존재해.

객체의 프로토타입과 배열의 프로토타입을 보자.

객체 → Object.prototype

배열 → Array.prototype → Object.prototype

이런 구조로 되어있는거야!!

→ 아~ 그래서 같은 객체이나 사용할 수 있는 메소드들이 다른 거 였구나!!


배열의 property 동적 생성

물론 배열도 Object 이기에 property를 추가해줄 수 있어. 하지만 그렇게 해서 추가하더라도

배열의 length에는 영향을 끼치지 않아!


배열요소 삭제

  1. delete : 해당하는 배열의 요소를 삭제하고 그 곳에 undefined 를 할당. length에는 변화x

             ( ex) delete arr[2] ; )
    
  2. splice : 해당하는 배열의 요소를 삭제하고 length 도 줄여줘


Array() 생성자 함수

: 호출할 때 인자 1개이고 숫자일 경우 호출된 인자를 length로 갖는 빈 배열 생성해줘

그 외의 경우라면 호출된 인자를 요소로 갖는 배열 생성해주는거야.

ex) ( var foo = new Array(3); , var bar = new Array(1,2,3) ; )


유사 배열 객체

: length 프로퍼티를 가진 배열이 아닌 객체를 유사 배열 객체라고 해!

유사 배열 객체의 가장 큰 특징은 배열 객체가 아님에도 불구하고, 자바스크립트의 표준 배열 메서드를 사용하는게 가능하단 거야.


기본 타입과 표준 메서드

: 그럼 기본타입은 객체가 아닌데 어떻게 메서드를 호출하는 겨??

→ 기본타입의 값들에 대해 객체 형태로 메서드를 호출할 경우, 이들 기본값은 메서드 처리 순간에 객체로 변환된 다음 각 타입별 표준메서드를 호출하게 되고 그 이후에 다시 기본값으로 복귀!!


typedef 연산자

문자열 - string

숫자 - Number

불린값 - boolean

null - object

undefined - undefined

객체 - object

배열 - object

함수 - function


==(동등) 연산자 vs ===(일치) 연산자

  1. ==연산자 : 비교하려는 피연산자의 타입이 다를 경우에 타입 변환를 거친다음 비교진행

  2. ===연산자 : 피연산자의 타입이 다르더라고 타입변경을 하지 않고 비교해.


!!연산자

: 피연산자를 불린값으로 변환하는거야!!

흠… 이건 어디에 쓸려고 있는걸까…


Chapter4 함수와 프로토타입 체이닝

함수정의

: 자바스크립트에서 함수를 생성하는 방법은 3가지야. 이에 따라 미묘~하게 동작이 차이가 난데.

  1. 함수 선언문
  2. 함수 표현식
  3. Function() 생성자 함수

함수 리터럴

: 자바스크립트에서는 함수도 일반 객체처럼 값으로 최급돼!! wow… 때문에 객체 리터럴 방식으로 일반 객체를 생성할 수 있는 것 처럼, 자바스크립트에서는 함수리터럴을 이용해 함수를 생성할 수 있어.

실제 함수 선언문이나 함수 표현식 방법 모두 이런 함수 리터럴 방식으로 함수를 생성한다 이말이야!

ex) function add(x,y){ return x+y; }

(자바스크립트에서 함수명은 명시를 안해줘두 돼!! → 익명함수가 되는거지)


함수 선언문 방식으로 함수 생성하기

: 선언문 방식은 리터럴과 형태는 같애. 여기서 주의할 것은 선언문 방식으로 정의된 함수의 경우 반드시 함수명이 정의되어 있어야한다는 거야


함수 표현식 방식으로 함수 생성하기

: 위에서 말했듯이 자바스크립트에서는 함수도 하나의 값처럼 취급되. 그렇기에 함수도 변수에 할당하는 것이 가능하다는거쥐!!

함수 리터럴로 하나의 함수를 만들고, 여기서 생성된 함수를 변수에 할당하여 함수를 생성하는 것을 함수표현식이라고 하는거야.

1
2
3
4
5
var add = function(x,y){
return x+y;
}
console.log(add(3,4));
}

이런식으로 말야!! 이때 저 add 라는 녀석은 함수 이름이 아니라 함수를 참조하는 변수인 걸 명심해.

add가 실제 참조하는 두 수를 더하는 함수의 이름은 없어. 이를 익명함수라고 한다 했지. 두 수를 더하는 익명함수를 만들고 이를 add 변수에 할당한거야. 이것이 바로 익명 함수를 이용한 함수 표현식 방법이야. (참고로 함수 이름이 포함된 함수 표현식을 기명함수 표현식이라고해.)

참고로 위에는 함수명을 명시하지 않았으나 예를들어 명시하였다고 하더라고 그 이름을 사용해서 외부에서 호출은 불가능해! 만약 표현식을 정의하는 몸체에서 재귀적 호출이 이루어진다면 이를 위해서 함수명을 명시하고 그 명을 사용하는거야!


function statement와 function expression에서의 세미콜론

: 일반적으로 자바스크립트 코드를 작성할 때 함수 선언문 방식으로 선언된 함수의 경우는 함수 끝에 세미콜론을 붙이지 않지만, 함수 표현식 방식의 경우는 세미콜론을 붙이는 걸 권장한다고 해!!


함수 호이스팅

: 함수를 생성하는 여러 방법들이 있는 걸 확인했는데 함수 선언문 보다는 함수 표현식을 사용하는 것을 선호해. 그 이유가 바로 함수 호이스팅에 있어. 함수 선언문 형태로 정의한 함수의 유효 범위는 코드의 맨 처음부터 끝까지야. 그렇기에 함수를 사용하기 전에 반드시 선언하지 않아도 사용가능하게 되고 이는 코드의 구조를 엉성하게 만들 수 있어. 그러나 표현식의 경우는 호이스팅이 일어나지 않기에 표현식으로 정의 된 이후에 그 함수를 사용할 수 있게 되는거야.


함수 객체

: 자바스크립트에서는 함수도 객체라 했자나! 여기에서 오는 성질이 하나 있찌. 즉 함수 자체가 일반 객체처럼 프로퍼티를 가질수가 있다는 거야. 일반적으로 함수를 선언하면 함수 함수 객체의 code라는 내부 프로퍼티에 자동으로 저장이 되는거야. 그리고 이 외에도 우리가 프로퍼티를 추가할 수 있는거지.


함수는 값으로 취급되는거야

: 계속해서 나오는 말이지만 함수는 객체야. 그렇기에 함수도 일반 객체처럼 취급될 수 있어. 그러면서 다음과 같은 동작이 가능해져.

  • 리터럴에 의해 생성
  • 변수나 배열의 요소, 객체의 프로퍼티 등에 할당 가능
  • 함수의 인자로 전달 가능
  • 함수의 리턴값으로 리턴가능
  • 동적으로 프로퍼티를 생성 및 할당가능

그리고 위의 것들이 가능한 녀석을 일급객체라고 불러. 그렇기에 자바스크립트에서는 함수를 일급객체라고 부르는거지.

그리고 값으로 취급된다는 것은 결국 함수의 파라메타 or return 등으로도 사용이 가능하다는 것을 뜻해.


함수 객체의 기본 프로퍼티

: 계~속해서 이야기하고 있듯이 자바스크립트에서 함수 역시 객체야. 이것은 함수 역시 일반적인 객체의 기능에 추가로 호출했을 때 정의된 코드를 실행하는 기능을 가졌다는거구 또한, 일반 객체와는 다르게 추가로 함수 객체만의 표준 프로퍼티가 있다는거야.

  • name : 함수의 이름
  • caller : 자신을 호출한 함수
  • arguments : 함수를 호출할 때 전달된 인자값
  • Prototype : Function.prototype ( 모든 함수들의 부모 객체는 Function Prototype객체고 Function Prototype의 부모 객체는 Object.prototype객체야! )
  • length : 함수가 정상적으로 실행될 때 기대되는 인자의 개수
  • prototye : 위의 Prototype 프로퍼티랑은 다른거구 이 함수가 생성자로 사용될 때 이 함수를 통해 생성된 객체의 부모역할을 하는 프로토타입 객체를 가리키구 그 녀석은 constructor 프로퍼티만 가지고 있어.

콜백함수

: 아까 익명함수에 대해 공부했짜너. 이 익명함수의 대표적인 용도가 콜백함수야. 콜백함수는 일반적으로 이벤트 핸들러의 처리에 사용되어져.


즉시 실행 함수

: 함수를 정의함과 동시에 바로 실행하는 함수를 즉시 실행함수라고 해! 그렇기에 같은 함수를 다시 호출할 수는 없어. 그래서 보통 최초 한번의 실행만을 필요로 하는 초기화 코드 부분에 사용할 수 있다는 거야. 형태는 다음과 같아

1
2
3
(function (name){
console.log('This is the immediate function -> ' + name);
})('foo');

이렇게야!! 보이듯이 여기서도 익명함수를 썼네. function (…){} 부분을 괄호로 감싼 뒤 그 뒤에 다시 괄호로 ‘foo’라는 녀석을 넣어주고 있어. 이렇게 될 경우 ‘foo’를 함수의 매개변수인 name으로 전달 되게 되는거야. 프레임워크나 라이브러리에 많이 쓰여. 실제 jQuery 코드에도 존재해.

그럼 왜 사용하는 걸까? 그 이유는 바로 함수 유포 범위 때문이야! 일반적으로 자바스크립트는 변수를 선언할 경우 프로그램 전체에서 접근할 수 있는 전역 유효 범위를 가지게 되자나. 그러나 함수 내부의 변수의 경우 그 함수 내부에서만 엑세스를 할 수 있는거지. 그렇기에 라이브러리 코드를 즉시 실행 함수 내부에 정의해두면 함수 외부에서 라이브러리의 변수들에 접근할 수 없고 그렇게 되면 이름 충돌같은 문제를 방지해서 전역네임스페이스가 더럽혀지지 않는 효과를 보는거야!!


내부 함수

: 자바스크립트에서는 함수 코드 내부에서도 다시 함수 정의가 가능해. 이렇게 함수 내부에 정의된 함수를 내부함수(inner function)이라고 불러. 내부함수는 클로저를 생성하거나 부모 함수 코드에서 외부에서의 접근을 막고 독립적인 헬퍼 함수를 구현하는 용도 등으로 사용되어져!

여기서 중요한건 접근가능 스코프 즉 범위야! 내부 함수에서는 자신을 둘러싼 부모 함수의 변수에 접근이 가능해(스코프체이닝). 내부함수는 일반적으로 자신이 정의된 부모 함수 내부에서만 호출이 가능하구. 즉 부모함수 외부에서 내부함수로 접근하는 것은 불가능하다 이말이야!

하지만 부모함수 외부에서 내부함수에 접근할 수 있게 끔 해줄 수 있는 방법이 있는데 그게 바로 클로저야! 부모함수가 내부함수를 반환하고 이를 외부에서 받게 되면 접근이 가능하게 되어지는거지!!