JavaScript 개념

Jnary·2022년 6월 23일
0

Web Application

목록 보기
1/3
post-thumbnail

0. JavaScript

1. 자바스크립트 기본 문법

  • 타입연산자 typeof
var a = typeof ‘Hi’; 	// “string”
//함수 정의
function square(number) {
    return number * number;
}

//객체
var person = {
    name : 'Jnary',
    gender: 'female',
    sayHello: function () {     //프로퍼티값으로 함수가 사용된 메소드
        console.log('Hi! My name  is ' + this.name);
    }
};
console.log(typeof person);     //object
console.log(person);            //{name: 'Jnary ..., sayHello: [Function: sayHello] }

//배열
var arr = [1, 2, 3, 4, 5];
console.log(arr[1]);

2. 데이터 타입과 변수

  • 자바스크립트는 동적 타입 언어 -> type inference
    primitive data type : boolean, null, undefined, number, string, symbol(es6+)
    변경 불가능한 값(immutable value), 값에 의한 전달(pass-by-value)
    1) number
    - 2진수, 8진수, 16진수 리터럴 모두 배정밀도 64bit 부동소수점 형식의 2진수로 저장
    - 참조하면 모두 10진수로 해석
    - 모든 수를 실수로 처리 (1 == 1.0, 3/2 == 1.5)
    - Infinity (양의 무한대), -Infinity (음의 무한대), NaN (허수)
    2) string
    - 큰 따옴표, 작은 따옴표 상관X (“ ‘’ ”, ‘ “” ‘ 가능)
    - 문자열은 유사 배열 -> 인덱스를 통해 접근 가능 (str[0] == ‘S’)
    - 한 번 생성된 문자열은 read only(immutable) -> 새로운 문자열 재할당
    - str = str.toUpperCase(); 대문자로 변환
    - str = str.substring(0, 3); 일부만 저장
    3) boolean
    - true(1) / false(0) : 비어있는 문자열, null, undefined, 0
    4) undefined
    - 선언 이후 값을 할당하지 않은 변수, 존재하지 않는 객체 프로퍼티에 접근
    - 처음 공간 할당 시 쓰레기 값으로 내버려두지 않고 undefined로 초기화
    (by. 자바스크립트 엔진)
    - 개발자가 임의로 사용X -> 개발자는 null 사용
    5) null
    - 자바스크립트는 대소문자 구별 (!= Null, NULL)
    - 의도적으로 변수에 값이 없음 명시(변수가 기억하는 주소의 참조 정보 제거)
    - 누구도 참조하지 않는 메모리 영역에 대해 가비지 컬렉션 수행
    - null타입 변수 typeof 시 object 반환 -> 설계상 오류
    - null타입 확인 시, typeof연산자가 아닌 === 일치 연산자 사용
    6) symbol
    - 이름의 충돌 위험이 없는 유일한 객체의 프로퍼티 키를 만들기 위해 사용
    - var key = Symbol(‘key’); //Symbol 함수 호출해서 생성
  • reference type : object
    object
    - 데이터와 그 데이터에 관련한 동작을 모두 포함할 수 있는 개념적 존재
    - 이름과 값을 가지는 데이터를 의하는 프로퍼티 & 동작을 의미하는 메소드를 포함할 수 있는 독립적 주체
  • 변수의 중복 선언 문법적으론 허용O (덮어쓰는 효과)
  • 변수 호이스팅(variable Hoisting)
    - var 선언문이나 function 선언문 등 모든 선언문이 해당 Scope의 선두로 옮겨진 것처럼 동작하는 특성
    -> 모든 선언문이 선언되기 이전에 참조 가능하다.
    ex.console.log(foo); //undefined
    var foo = 123;
    console 전에 var foo = 123; 이 호이스팅되어 var foo; 실행
    블록 레벨 스코프가 아닌 함수 레벨 스코프 (단, let, const로 블록 레벨 사용가능)
  • var 키워드의 문제점
    1) 함수 레벨 스코프
    - 전역 변수 남발
    - for loop 초기화식에서 사용한 변수를 외부에서도 참조 가능
    2) var 키워드 생략 허용
    - 의도치 않은 변수의 전역화
    3) 중복 선언 허용
    - 의도치 않은 변수값 변경
    4) 변수 호이스팅
    - 변수 선언 전 참조 가능
    -> 이러한 단점 보완하기 위해 let, const 키워드 도입

3. 연산자

  • 표현식과 값은 동등한 관계(동치)다. -> 값이 위치할 수 있는 자리에는 표현식도 위치
  • 문(statement) : 리터럴, 연산자, 표현식, 키워드 등으로 구성
    코드블록 제외하고 세미콜론(;)으로 끝나야함
    -> 세미콜론 자동 삽입 기능(ASI) 존재.
  • 표현식 vs 문
    1) 표현식 : 평가되어 값을 만듦. 그 이상의 행위X
    2) 문 : 선언 키워드를 사용하여 변수나 함수를 생성.
    - 프로그램의 흐름을 제어
    - 표현식으로 생성한 값을 사용해 컴퓨터에게 명령을 내리는 것
    - 표현식인 문(ex. 할당문), 표현식이 아닌 문(ex. 선언문)
  • 연산자
    1) 산술 연산자
    - 산술 연산 할 수 없는 경우 NaN 반환
    - 이항과 달리, 단항(++. --)은 피연산자의 값을 변경하는 부수 효과를 가짐
    - 단항 + 연산자는 아무런 효과X. 숫자가 아닌 피연산자에 사용시 숫자로 반환
    - +’10’ // 10 , -’10’ // -10
    2) 문자열 연결 연산자 +
    3) 할당 연산자 =
    4) 비교 연산자
    - ‘===’ 일치 연산자 : 타입이 같은지 다른지 반환 / ‘!==’
    - 5 == ‘5’ //암묵적 타입 변환
    - NaN !== NaN //NaN은 자신과 일치하지 않는 유일한 값 -> isNaN(NaN)
    5) 논리 연산자
    - 일반적으로 boolean값을 반환(논리합 ||, 논리곱 &&에서는 아닐 수도)
    - 단축 평가
    6) 쉼표 연산자
    - 왼쪽 피연산자부터 차례대로 피연산자를 평가
    - 마지막 피연산자의 평가가 끝나면 마지막 피연산자의 평가 결과를 반환
    - x=1, y=2, z=3; // 3
    7) 그룹 연산자
    - 그룹 내의 표현식을 최우선으로 평가
    8) 타입 연산자 typeof
	typeof NaN 		// number
	typeof Symbol() 	// symbol
	typeof null		// object
	typeof [] 		// object
	typeof {} 		// object
	typeof new Jnary() 	// object
	typeof /test/gi 	// object
	typeof f() {} 		// function
	- 선언하지 않은 식별자의 경우, ReferenceError 가 아닌 undefined 반환

4. 제어문

  • 삼항연산자 활용
    var kind = num ? (num > 0 ? ‘양수’ : ‘음수’) : ‘영’;
  • switch문에서 case문 중복 가능
	switch(month) {
		case 1: case 3: case 5: case 7: case 8: case 10: case 12:
			days = 31;
			break;}
  • 레이블문 (권장X, 가독성 저하, 오류발생 가능성)
	foo : {
		break foo; 	// foo 레이블 블록문 탈출
	}
- 내부 반복문이 아닌 외부 반복문을 탈출할 때 사용

5. 타입 변환과 단축 평가

  • 암묵적 타입 변환 ( by. 자바스크립트 엔진 ) =타입 강제 변환(Type coercion)
  • 명시적 타입 변환 ( by. 개발자 ) =타입 캐스팅(Type casting)
  • 문자열 인터폴레이션
    - 암묵적으로 문자열 타입으로 변환
    - 1+1 = ${1+1} // 1+1 = 2
  • 문자열 타입으로의 암묵적 변환
    - null + ‘ ‘ // “null”
    - (Symbol()) + ‘ ‘ // TypeError : Cannot convert a Symbol value to a string
    - ({ }) + ‘ ‘ // “[object Object]”
    - Math + ‘ ‘ // “[object Math]”
    - [ ] + ‘ ‘ // “ “
    - [10, 20] + ‘ ‘ // “10, 20”
    - (function(){ }) + ‘ ‘ // “function() { }”
    - Array + ‘ ‘ // “function Array() { [native code] }”
  • 숫자 타입으로의 암묵적 변환
    - 1/’one’ // NaN
    - +’ ‘ // 0
    - +’1’ // 1
    - +true // 1
    - +null // 0
    - +undefined // NaN
    - +Symbol() // TypeError : Cannot convert a Symbol value to a number
    - + { }, +[10,20], +(f(){}) // NaN
    - + [ ] // 0
  • boolean 타입으로의 암묵적 변환
    - Truthly값(참으로 인식할 값)
    - Falsy값(거짓으로 인식할 값) : false, undefined, null, 0, -0, NaN, (빈문자열)
    —------------------------------------------------------------------------------------
  • 문자열 타입으로의 명시적 변환
    1) String 생성자 함수를 new 연산자 없이 호출
    String(NaN) // “NaN”
    2) Object.prototype.toString 메소드 사용
    (Infinity).toString() // “Infinity”
    3) 문자열 연결 연산자 이용
    true + ‘ ‘ // “true”
  • 숫자 타입으로의 명시적 변환
    1) Number 생성자 함수를 new 연산자 없이 호출
    Number(‘0’) // 0
    2) parseInt, parseFloat 함수 사용(문자열만 변환 가능)
    parseFloat(‘3.14’) // 3.14
    3) 단항 연결 연산자 사용
    +true // 1
    4) 산술 연산자 사용
    ‘9.21’ * 1 // 9.21
  • boolean 타입으로의 명시적 변환
    1) Boolean 생성자 함수를 new 연산자 없이 호출
    Boolean(NaN) // false
    2) ! 부정 논리 연산자 두번 사용
    !!’x’ // true
    —------------------------------------------------------------------------------------
  • 단축 평가
    - 논리 연산자는 논리 연산의 결과를 결정한 피연산자의 평가 결과를 반환
    ex. ‘Cat’ && ‘Dog’ // “Dog”, ‘Cat’ || ‘Dog’ // “Cat”
    - 활용
    1) 객체가 null인지 확인하고 프로퍼티를 참조할 때
    console.log(obj && obj.value) // TypeError 발생 방지
    2) 함수의 인수(argument) 를 초기화할 때
function getStringLength(str) {
	str = str || ‘ ‘; return str.length;
} getStringLength(); 			// 0 -> undefined로 인한 에러 방지

6. 객체

  • 객체의 특성
    - key와 value로 구성된 Property들의 집합
    - property (데이터) & method (데이터를 참조,조작할 수 있는 동작)
    - 함수 : 일급 객체. 프로퍼티 값으로 사용가능 (-> 메소드)
    - 객체는 prototype(객체의 프로퍼티와 메소드)을 상속받을 수 있다.
  • 객체 구성
1) property
	- 프로퍼티 키(프로퍼티 식별자) & 프로퍼티 값
	- 프로퍼티 키 : 빈 문자열을 포함하는 모든 문자열 or symbol 값
				 중복 선언시 덮어씀.
                 이외의 값 지정시 문자열로 암묵적 타입 변환
2) method
	- 객체에 제한되어 있는 함수
  • 객체 생성
    - 자바스크립트는 프로토타입 기반 객체지향 언어 -> 클래스X
    rf> ES6부터 클래스 도입
    : 클래스도 사실 함수이고 기존 프로토타입 기반 패턴의 문법적 설탕

1) 객체 리터럴

	var person = {
		name: ‘Jnary’,
		gender:'female',
        sayHello: function() {
        	console.log('Hi! My name is '+this.name);
        }
    };

2) Object 생성자 함수
- var person = new Object(); //빈 객체 생성
- person.name = 'Jnary'; //프로퍼티 추가

3) 생성자 함수
- 동일한 프로퍼티를 갖는 다른 객체들 생성시 유용 (like 클래스)

	// 생성자 함수
	function Person(name, gender) {
     var married = true; 	//private
     this.name = name;		//public
     this.gender = gender;
   }
	// 인스턴스의 생성
	var person1 = new Person('Jnary', 'female');
	var person2 = new Person('Mingu', 'male');

-이름은 일반적으로 대문자로 시작
-this에 바인딩된 프로퍼티와 메소드는 public, 그 외 private

  • 객체 프로퍼티 접근

1) 프로퍼티 키
- 일반적으로 문자열을 지정
- 이외의 값 지정시, 문자열로 암묵적 타입 변환
- 유효한 이름인 경우, 따옴표 생략 가능
- 예약어X (ex. abstract, char, const, yield ...)
- 표현식을 프로퍼티키로 사용시, 대괄호 필수

2) 프로퍼티 값 읽기
- console.log(person['first-name']); //예약어 || 유효하지 않은 이름
- console.log(person.gender);
- console.log(person['gender']); //예약어X && 유효한 이름
- 대괄호 표기법의 경우 내에 들어가는 이름은 반드시 문자열(따옴표 생략 X)
- 객체에 존재하지 않는 프로퍼티 참조시, undefined 반환

3) 프로퍼티 값 갱신
- 소유한 프로퍼티에 새로운 값 할당 시, 프로퍼티 값 갱신

4) 프로퍼티 동적 생성
- 소유하지 않은 프로퍼티 키에 값 할당 시, 주어진 키-값 객체에 추가

5) 프로퍼티 삭제
- delete person.gender; delete 연산자로 프로퍼티 삭제
- delete연산자의 피연산자 : 프로퍼티 키

6) for-in문
- 객체(배열 포함)에 포함된 모든 프로퍼티에 대해 루프 수행
- 객체의 문자열 키를 순회하기 위한 문법
- 배열의 경우 prop에 index반환
- 단, 반환되는 순서는 보장X
- 배열의 요소들만을 순회X

	for (var prop in person) {
      console.log(prop + ': ' + person[prop]);
    }

cf. for-of문 (ES6~)
for(const value of array) { console.log(value); }
- 배열의 요솜들만을 순회하기 위해 사용

  • Pass-by-reference
    - 객체 자체 저장 X, 생성된 객체의 참조값 저장
    • var bar = foo //참조값 전달, 같은 객체 가리킴
  • Pass-by-value
    - 객체는 Pass-by-reference, 원시타입은 Pass-by-value
    • 원시 타입은 값이 한 번 정해지면 변경 불가(immutable)
    • 참조 타입이 아닌 값 자체가 저장
  • 객체의 분류

    1) Built-in-Object (내장객체)
    - 웹페이지 등을 표현하기 위한 공통의 기능 제공
    2) Host Object (사용자 정의 객체)
    - 사용자가 정의하고 확장시킨 객체
    - Built-in-Object와 Native Object가 구성된 이후에 구성됨

7. 객체와 변경불가성(Immutability)

  • immutable value vs. mutable value
    - 원시 타입은 immutable value (변경X, 재할당은O)
    - 원시 타입 : Boolean, null, undefined, Number, String, Symbol
    - 그 외 객체 타입은 mutable value
  • 불변 데이터 패턴(immutable data pattern)
    - 의도하지 않는 객체의 변경 발생의 해결법 : 불변객체로 만들어 프로퍼티의 변경 방지.
    - 변경이 필요한 경우 참조가 아닌 객체의 방어적 복사(defensive copy)로 새로운 객체 생성후 변경

1) Object.assign (객체의 방어적 복사)
- 타깃 객체로 소스 객체의 프로퍼티 복사
- 동일한 프로퍼티는 소스 객체의 프로퍼티로 덮어쓰기
- 리턴값으로 타깃 객체 반환
- ES6~, Internet Explorer 지원X
- deep copy는 지원X, Nested Object는 Shallow copy됨.
- Object.assign(target, ...sources)

			const o1 = {a:1};
			const o2 = {b:2};
			const o3 = {c:3};
			const merge = Object.assign(o1, o2, o3);
			console.log(o1); 	// {a:1, b:2, c:3} 타깃 객체는 변경
			const merge2 = Object.assign({}, o1); 	// 변경X
			console.log(merge2===o1); 	//false 참조값 

2) Object.freeze (불변객체화를 통한 객체 변경 방지)
- Object.freeze(o1);
- o1.a = 21; 무시된다.
- console.log(Object.isFrozen(o1)); //true
- Nested Object는 변경 가능!
- Nested Object도 변경 불가능하게 하려면 Deep freeze가 필요

			function deepFreeze(obj) {
              const props = Object.getOwnPrepertyNames(obj);
              props.forEach((name) => {
                const prop = obj[name];
                if (typeof prop === 'object' && prop !== null) {
                  deepFreeze(prop);
                }
              });
              return Object.freeze(obj);
            }

3) immutable.js
- Object.assign, Object.freeze 큰 객체에권장X (성능상 이슈)
- Facebook에서 제공하는 또 다른 대안
- 영구불변 데이터 구조를 제공
(List, Stack, Map, Set, OrderedSet, Record)
- $npm install immutable immutable.js 설치

			const{Map} = require('immutable')
            const m1 = Map({a:1, b:2, c:3})
            const m2 = m1.set('b', 50)
            //.set()은 결과를 반영한 새로운 객체를 반환
            m1.get('b') 	//2
			m2.get('b') 	//50

8. 함수

  • 함수 정의

1) 함수 선언문
- 매개변수 타입 기술X -> 몸체 내 매개변수 타입 체크 필요
- function square(number) { return number*number; }

2) 함수 표현식
- 무명의 리터럴로 표현 가능
- 변수나 자료구조(객체, 배열..) 에 저장 가능
- 함수의 파라미터로 전달 가능
- return값으로 사용 가능
- 함수 표현식 : 함수 리터럴 방식으로 함수를 정의하고 변수에 할당하는 방식
- var square = function(number) {return number*number;};
- 함수명 생략 가능 -> 익명함수 (anonymous function)
- 생략 안 한 함수는 기명 함수 (named function)
- 함수를 할당한 변수는 할당된 함수를 가리키는 참조값 저장
- 함수 호출시, 함수를 가리키는 변수명 사용
- 기명함수명 사용시 에러 -> 함수표현식에서 사용한 함수는 외부 코드에서 접근 불가능
- 기명함수명은 자신을 재귀적 호출하거나 자바스크립트 디버거가 함수를 구분할 수 있는 식별자 역할을 함
- console.log(square(10)); //100

3) Function 생성자 함수
- 함수 선언문, 함수 표현식 모두 함수 리터럴 방식으로 함수를 정의함.
-> 이는 내장 함수 Function 생성자 함수로 함수를 생성하는 것을 단순화시킨 축약법임.
- new Function(arg1, arg2, ... argN, functionBody)
- var square = new Function('n', 'return n*n');
- 일반적으로 사용 X

  • 함수 호이스팅
    1) 함수선언문에서 함수 호이스팅
    - 함수가 정의되기 이전에 함수 호출 가능

    • let, const를 포함하여 모든 선언 = 호이스팅
    • 호이스팅 : 모든 선언문이 해당 Scope의 선두로 옮겨진 것처럼 동작하는 특성
    • 자바스크립트 엔진이 스크립가 로딩되는 시점에 바로 초기화 후 VO(Variable Object)에 저장
    • 즉, 함수 선언, 초기화, 할당이 한 번에.
      2) 함수표현식에서 함수 호이스팅
      - 함수 표현식의 경우, 함수 호이스팅이 아닌 변수 호이스팅 발생
    • 변수 호이스팅 : 변수 생성, 초기화, 할당이 분리되어 진행
    • 호이스팅된 변수는 undefined로 초기화, 실제값 할당은 할당문에서
      -> 함수표현식 권장
  • First-class object (일급 객체)
    - 일급 객체 : 생성, 대입, 연산, 인자, 반환값으로서의 전달 등 프로그래밍 언어의 기본적 조작을 제한없이 사용할 수 있는 대상
    - 일급 객체 조건
    1) 무명의 리터럴로 표현 가능
    2) 변수나 자료구조에 저장 가능
    3) 함수의 매개변수에 전달 가능
    4) return값으로 사용 가능
    - 함수와 다른 객체를 구분짓는 특징은 호출할 수 있다는 것.

  • 매개변수 (Parameter, 인자) vs. 인수(argument)
    - 함수에 전달한 인수는 매개변수에 할당됨.
    - 인수 전달X -> 매개변수는 undefined로 초기화
    - 초과된 인수는 무시됨.
    - Call-by-reference : 함수 내에서 값 변경 시, 원본 객체가 변경되는 부수효과 발생
    - 부수효과를 발생시키는 비순수함수(Impure fucntion)는 복잡성 증가 -> 지양

  • 반환값
    - 배열 등을 통해 한 번에 여러 개의 값 리턴 가능
    - 반환 생략 시, 암묵적으로 undefined 반환

  • 함수 객체의 프로퍼티
    - 일반 객체와는 다른, 함수만의 프로퍼티를 가짐.

    function square(n) { return n * n; }
    square.x = 10;
    console.log(square.x);

    - console.dir(square)

    1) arguments 프로퍼티
    - 함수 호출 시, 전달된 인수들의 정보를 담고 있는 순회가능한(iterable) 유사배열객체
    - 유사배열객체 : length 프로퍼티를 가진 객체, 배열메소드 사용X
    - 함수 내에서 지역변수처럼 사용 (외부에서 X)
    - 가변 인자 함수 구현시 유용
    - 함수 호출 시, 인수들과 함께 암묵적으로 arguments 객체나 함수 내부로 전달

    function sum(...args) {
    if(!args.length) return 0;
    return args.reduce((pre,cur) => pre + cur);

    2) caller 프로퍼티
    - 자신을 호출한 함수
    - foo(bar) -> bar.caller = function foo(func) {...}
    3) length 프로퍼티
    - 함수 정의 시, 작성된 매개변수의 개수
    - arguments.length값과 다를 수 있음
    4) name 프로퍼티
    - 함수명. 익명함수의 경우 빈문자열
    - var namedFunc = function Jnary(a,b) { ... }
    - console.log(namedFunc.name); //Jnary
    5) __proto 접근자 프로퍼티
    - 모든 객체는 [[Prototype]] 이라는 내부 슬롯을 가짐.
    - 내부 슬롯은 프로토타입 객체를 가리킴.
    - 프로토타입 객체 : 프로토타입 기반 객체 지향 프로그래밍의 근간을 이루는 객체로서 객체간의 상속을 구현하기 위해 사용됨.
    - 즉, 다른 객체에 공유 프로퍼티를 제공하는 객체.
    - __proto
    프로퍼티는 [[Prototype]] 내부 슬롯이 가리키는 프로토타입 객체에 접근하기 위해 사용하는 접근자 프로퍼티
    - 내부 슬롯에 접근X -> 간접적 접근 방법 제공하는 경우에만 가능
    - [[prototype]] 내부 슬롯에도 직접 접근X
    - __proto 접근자 프로퍼티를 통해 간접 접근
    - 객체 리터럴로 생성한 객체의 프로토타입 객체는 Object.prototype
    - 객체가 직접 소유하는 프로퍼티X -> 모든 객체의 프로토타입 객체인 Object.prototype 객체의 프로퍼티
    - 모든 객체는 상속을 통해 __proto
    접근자 프로퍼티 사용 가능
    6) prototype 프로퍼티
    - 함수 객체만이 소유하는 프로퍼티 -> 일반 객체에는 X
    - console.log(Object.getOwnPropertyDescriptor({}, 'prototype')); //undefined

  • 함수의 다양한 형태
    1) 즉시 실행 함수
    - IIFE (Immediately Invoke Function Expression)
    - 함수의 정의와 동시에 실행되는 함수
    - 최초 한 번만 호출, 다시X
    - 초기화 처리 등에 사용
    - (function myfunc() { ... }());
    2)
    3)

" 본 포스팅은 PoiemaWeb을 바탕으로 정리한 것입니다. "

profile
숭실대학교 컴퓨터학부 21

0개의 댓글