javascript-3

원시 값과 객체의 비교

원시 타입 vs 객체 타입

원시타입 : immutable value
객체타입 : mutable value
원시 값을 변수에 할당하면 변수에는 실제 값이 저장
객체를 변수에 할당하면 변수에 참조 값이 저장
Pass by value : 원시 값을 갖는 변수를 다른 변수에 할당하면 원본의 원시 값이 복사
Pass by referencce : 객체를 가리키는 변수를 다른 변수에 할당하면 원본의 참조 값이 복사

원시값

변경 불가능한 값

immutable value : 변경 불가능한 값, read only
재할당과는 다른 의미
원시 값을 갖는 변수에 다른 값을 넣으면 기존 메모리에 값이 변경되는 것이 아니라 새로운 메모리 공간을 확보하고 재할당한 원시 값을 저장
변수가 참조하던 메모리 공간의 주소가 바뀜

문자열과 불변성

문자열은 0개 이상인 문자(character)들의 집합
한개의 문자는 2byte의 메모리 공간에 저장
문자열 타입의 값은 몇개의 문자로 이루어졌는지에 따라 필요한 메모리 공간의 크기가 결정
자바스크립트의 문자열은 원시타입으로 변경 불가능

유사배열
배열은 아니지만 마치 배열처럼 처리가능, 문자열은 배열처럼 인덱스를 통해 각 문자에 접근할 수 있으며 for문으로 순회 가능, length 프로퍼티를 갖는 객체일 수 있음

값에 의한 전달

할당한 변수가 원시 타입이라면 할당한 변수값이 복사되어 전달 -> Pass by value
변수를 다른 변수에 할당하면 두 변수의 값은 동일하지만 메모리 공간의 주소는 다름
변수의 값을 변경해도 다른 변수의 값은 불변

객체

프로퍼티의 개수가 정해져 있지 않으며 동적으로 추가, 삭제 가능
프로퍼티의 값에도 제약이 없음
원시 값과 같이 확보해야 할 메모리 공간의 크기를 사전에 정해 둘 수 없음

자바스크립트는 클래스 없이 객체를 생성할 수 있으며 생성 후 동적으로 프로퍼티와 메소드를 추가 할 수 있음

변경 가능한 값

객체를 할당한 변수는 참조 값을 갖음

객체를 변경할 때 마다 원시 값처럼 이전 값을 복사하여 새롭게 생성한다면 명확하고 깔끔하지만 객체는 크기가 매우 클 수도 있고 프로퍼티 값이 객체일 수도 있어 복사하고 생성하는데 많은 비용 필요

원시 값처럼 객체 자체를 복사하여 다시 생성하는 것을 깊은 복사, 참조 값을 복하는 것을 얕은 복사라 함

객체는 여러 개의 식별자가 하나의 객체를 공유할 수 있음

참조에 의한 전달

두 식별자가 하나의 객체를 공유
원본 또는 사본 어떤 곳에서 객체를 변경하면 서로 영향을 받음

함수

함수

일련의 과정을 문(statement)들로 구현하고 코드 블록으로 감싸서 하나의 실행 단위로 정의한 것
프로그래밍 언어의 함수도 입력을 받아서 출력
매개변수(parameter) : 입력을 전달받는 변수
인수(argument) : 입력
반환값(return value) : 출력

함수가 여러개 존재 할 수 있으므로 특정 함수를 구별하기 위해 식별자인 함수명을 사용

함수는 함수 정의를 통해 생성
함수 정의만으로 함수는 실행되지 않음
미리 정의된 일련의 과정을 실행하기 위해 필요한 입력, 즉 인수를 매개변수를 통해 함수에게 전달하면서 함수의 실행을 지시해야 함 -> 함수 호출

함수 호출을 하면 코드 블록에 담긴 문들이 일괄적으로 실행되고 결과를 반환

함수의 사용 이유

필요할 때 여러 번 호출 가능
동일 작업을 반복 수행할 때 같은 코드의 중복을 제거 -> 코드의 재사용

유지보수의 편의성을 높이고 실수를 줄여 코드의 신뢰성을 높이는 효과

함수 리터럴

객체는 객체 리터럴 표기법으로 생성
함수도 함수 리터럴로 생성
일반 객체는 호출 불가, 함수는 호출 가능

함수 리터럴은 function 키워드, 함수명, 매개변수 목록 그리고 함수 몸체로 구성

함수명

  • 함수명은 식별자 -> 네이밍 규칙 준수
  • 몸체 내에서만 참조 가능
  • 생략가능 -> 익명함수

매개변수 목록

  • 0개 이상 매개변수를 괄호로 감싸고 쉼표로 구분
  • 매개변수에는 인수가 할당
  • 함수 몸체 내에서 변수와 동일 취급

함수 몸체

  • 함수가 호출되었을 때 일괄적으로 실행될 문들을 하나의 실행 단위로 정의한 코드 불록
  • 함수 호출에 의해 실행

함수 vs 일반 객체
함수는 객체
일반 객체는 호출 불가
함수는 고유한 프로퍼티 보유

함수 정의

정의 방법

  • 함수 선언문
  • 함수 표현식
  • function 생성자 함수
  • 화살표 함수 : ES6

함수 선언문

함수 리터럴 표기법과 동일 형태
함수명 생략 가능

함수명을 호출하는 것이 아니라 함수 객체를 가리키는 변수를 호출
함수 선언문 방식으로 생성된 함수를 호출한 것은 함수명이 아니라 자바스크립트 엔진이 암묵적으로 생성한 변수
함수명과 변수명이 일치하여 함수명으로 호출되는 듯 보이나 변수명으로 호출된 것

자바스크립트 엔진은 함수 선언문을 함수 표현식으로 변환하여 함수 객체를 생성한다 생각 할 수 있음

함수 표현식

함수는 일급 객체이므로 함수 리터럴로 생성한 함수 객체를 변수에 할당가능 -> 함수 표현식
함수 표현식의 함수 리터럴은 함수명을 생략하는 것이 일반적

함수 선언문은 표현식이 아닌 문이고 함수 표현식은 표현식인 문

함수 선언문 vs 함수 표현식

// 함수 선언문
var add = function add(x, y) {
return x + y;
};

// 함수 표현식
var add = function (x, y) {
return x + y;
};

함수 생성 시점과 함수 호이스팅

함수 선언문으로 정의한 함수와 함수 표현식으로 정의한 함수의 생성시점은 다름
함수 선언문은 코드의 선두로 끌어 올려진 것처럼 동작 -> 함수 호이스팅

함수 호이스팅 vs 변수 호이스팅

변수 호이스팅은 선언 단계와 초기화 단계가 동시에 진행되며 다른 코드가 실행되기 이전에 수행
함수 호이스팅은 선언 단계와 초기화 단계, 할당당계가 동시 진행

Function 생성자 함수

생성자 함수 : 객체를 생성하는 함수, 객체를 생성하는 방식은 객체 리터럴 이외 다양한 방범이 존재

var add = new Function(‘x’, ‘y’, ‘return x + y’);

Function 생성자 함수 방식으로 생성한 함수는 렉시컬 스코프를 만들지 않고 전역 함수인 것처럼 스코프를 생성
클로저도 생성하지 않음

화살표 함수

ES6에서 도입
항상 익명 함수로 정의
기존 함수와 this 바인딩 방식이 다르고 prototype 프로퍼티가 없고 arguments 객체를 생성하지 않음

함수 호출

함수를 참조하는 변수와 한 쌍의 소괄호인 함수 호출 연산자로 호출
0개 이상의 인수를 쉼표로 구분하여 나열
인수는 매개변수에 할당할 수 있는 값

함수를 호출하면 현재 실행 흐름을 중단, 호출된 함수로 컨트롤 이관
매개변수에 인수가 할당되고 함수 몸체의 문들이 실행

매개변수와 인수

함수의 실행을 위해 함수 외부에서 함수 내부로 값을 전달할 필요가 있는 경우, 매개변수를 통해 인수를 전달
함수를 호출할 때 지정하며 개수와 타입에 제한이 없음

함수를 호출할 때 매개변수의 개수만큼 인수를 전달하는 것이 일반적
그렇지 않아도 에러가 발생하지는 않음
함수는 매개변수의 개수와 인수의 개수를 체크하지 않음
인수가 부족한 경우 매개변수의 값은 undefined

인수가 매개변수보다 만은 경우, 초과되는 인수는 무시
-> 암묵적으로 모든 인수는 arguments 객체의 프로퍼티로 보관

인수 확인

자바스크립트 함수는 매개변수와 인수의 개수가 일치하는지 확인하지 않음
동적타입 언어로 매개변수의 타입을 사전에 지정하지 않음
-> 적절한 인수가 전달되었는지 확인 필요

매개변수의 개수

매개변수의 최대 개수 제한은 ECMAScript 스펙에 정해져 있지 않음
-> 브라우저마다 제각각

일반적으로 3개 이하 0개가 가장 이상적

외부 상태의 변경과 함수형 프로그래밍

원시값 : 값에 의한 전달
객체 : 참조에 의한 전달
매개변수도 함수 몸체 내부에서 동일 취급

값에 의한 전달은 값이 복사되는 것으로 원본 보장
참조에 의한 전달은 원본 훼손 발생

반환문

함수는 return 키워드와 반환값으로 이루어진 반환문을 사용하여 실행 결과를 반환

반환문은 함수의 실행을 중단, 함수 몸체를 빠져나가는 역활과 return 키워드 뒤에 지정한 값을 반환

return 키워드 뒤에 반환값을 명시적으로 지정하지 않으면 undefined가 반환
반환문을 생략하면 암묵적 undefined 반환

다양한 함수의 형태

즉시실행함수

함수의 정의와 동시에 즉시 호출 -> IIFE
한번만 호출되며 다시 호출 불가
함수 선언문이나 함수 표현식을 그룹 연산자로 감싸면 함수가 평가되어 함수 객체가 됨

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
(function() {
// ...
})();

(function() {
// ...
})();

!(function() {
// ...
})();

+(function() {
// ...
})();

모두 가능하지만 일반적으로 처음 방법을 사용

즉시 실행 함수 내에 코드를 모아두면 혹시 있을 수 있는 변수명 또는 함수명의 충돌을 방지

재귀 함수

함수가 자기 자신을 호출하는 것
반드시 탈출 조건이 필요 -> 없을 경우 무한히 연쇄 호출

대부분 for문이나 while문으로 구현 가능
-> 재귀함수를 사용하는 것이 반복문을 사용하는 것보다 직관적으로 이해하기 쉬울 때에만 한정적 사용이 바람직

중첩 함수

함수 내부에 정의된 함수
일반적으로 자신을 포함한 외부함수를 돕는 헬퍼함수의 역활

콜백함수

자바스크립트의 함수는 일급 객체로 함수의 인수로 함수 전달 가능
콜백함수는 콜백 함수를 인수로 전달 받은 함수가 호출 시점을 결정하여 호출

콜백 함수가 콜백 함수를 전달받는 함수 내부에만 호출된다면 익명 함수 리터럴로 정의하면서 곧바로 전달하는 것이 일반적
이때 콜백함수로서 전달된 함수 리터럴은 콜백 함수를 전달받은 함수가 호출될 때 평가되어 생성
단, 콜백 함수를 다른 곳에서도 호출할 필요가 있거나, 콜백 함수를 전달 받는 함수가 자주 호출된다면 함수 외부에서 정의 후 변수를 전달하는 것이 효율적

중첩 함수가 외부 함수를 돕는 헬퍼 함수의 열활을 하는 것 처럼 콜백 함수는 함수에 전달되어 헬퍼 함수의 역활 수행
중첩 함수는 고정되어 교체 불가, 콜백하뭇는 외부에서 인수로 주입하기 때문에 자유롭게 교체 가능

스코프

유효범위
식별자를 검색하는 규칙

스코프란?

변수는 자신이 선언된 위치에 의해 자신이 유효한 범위, 즉 다른 코드가 변수 자신을 참조할 수 있는 범위가 결정 -> 스코프(Scope, 유효범위)

스코프라는 개념이 없다면 전체 프로그램에서 동일 변수명은 사용이 불가

var 키워드로 선언된 변수는 같은 스코프 내에서 중복 선언이 허용 -> 의도치 않게 변수 값이 변경되는 부작용 발생
let, const 키워드로 선언된 변수는 같은 스코프내에서 중복 선언을 허용하지 않음

스코프의 종류

전역 : 코드의 바깥 영역 -> 전역 스코프, 전역 변수
지역 : 함수 몸체 내부 -> 지역 스코프, 지역 변수

전역과 전역 스코프

전역이란 코드의 가장 바깥 영역
전역은 전역 스코프를 생성
전역에 변수를 선언하면 전역 스코프를 갖는 전역 변수가 됨
전역 변수는 어지서든 참조 가능

지역과 지역 스코프

지역이란 함수 몸체 내부
지역 변수는 자신의 지역 스코프와 하위 지역 스코프에서 유효
전역과 지역에 동일한 변수명이 있고 지역에서 해당 변수를 찾는 다면 지역에 선언된 변수를 참조

스코프 체인

스코프는 함수의 중첩에 의해 계충적 구조를 갖음
외부 함수의 지역 스코프를 중첩 함수의 상위 스코프라 함
-> 이렇게 스코프가 계층적으로 연결된 것을 스코프 체인이라 함

변수를 참조할 때, 자바스크립트 엔진은 스코프 체인을 통해 변수를 참조하는 코드의 스코프에서 시작하여 상위 스코프 방향으로 이동하며 선언된 변수를 검색

상위 스코프에서 유요한 변수는 하위 스코프에서 자유롭게 참조할 수 있지만 하위 스코프에서 유효한 변수를 상위 스코프에서 참조할 수 없음

함수를 어디서 호출했는지가 아닌 어디에 정의 했는가에 따라 상위 스코프를 결정

암묵적 전역 변수

선언하지 않은 변수에 값을 할당하면 자바스크립트 엔진은 아무런 에러없이 암묵적으로 전역 변수를 선언하고 값을 할당 -> 암묵적 전역 변수

자바스크립트는 파일마다 독립적인 파일 스코프를 갖지 않음
-> 하나의 전역

Your browser is out-of-date!

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

×