Language/Java Script

[JavaScript] 기본 요약 정리

마탁이 2021. 1. 22. 16:15

1. JavaScript

 - 유형 및 연산자, 표준 내장 객체 및 메소드가 있는 다중 패러당미, 동적 언어.

 - 구문은 Java 및 C 언어를 기반으로 둠.

 - JavaScript는 클래스 대신 객체 프로토 타입을 사용하여 객체 지향 프로그래밍을 지원.

   함수는 객체이며, 함수는 실행 가능한 코드를 유지하고 다른 객체와 마찬가지로 전달될 수 있다.

 

 

2. JavaScript의 Type

  • 수 (Number)
  • 문자열 (String)
  • 부울 (Boolean)
  • 객체 (Object)
    • 함수 (Function)
    • 배열 (Array)
    • 날짜 (Date)
    • 정규식 (RegExp)
  • 널 (Null)
  • 정의되지 않음 (Undefined)

 


3. 수 (Number)

 - parseInt() 함수를 사용하여 문자열을 정수로 변환할 수 있다.

   (parseFloat() 함수도 있지만 parseInt() 와는 달리 항상 10진수를 사용한다.)

 - 문자열이 수가 아닌 경우 NaN(Not a Number) 로 불리는 값을 Return 한다.

console.log(parseInt('123', 10));

 - 덧셈, 뺄셈, 게수 (또는 나머지) 연산을 포함하는 표준 산술 연산자가 지원된다.

   또한, Math 내장 객체가 있다.

console.log(Math.sin(3.5));

var r = 10;
var circumference = 2 * Math.PI * r;
console.log(circumference);

 - JavaScript는 특별한 값 Infinity와 -Infinity를 가지고 있다.

console.log(1 / 0);
console.log(-1 / 0);

 

4. 문자열 (String)

 - JavaScript에서 문자열은 유니코드 문자들이 연결되어 만들어진 것.

   (각각 16 bit 숫자로 표현된 UTF-16 코드 유닛이 길게 이어져있는 것)

 - 문자열 역시 객체로 취급된다.

 

5. undefined / null

 - JavaScript는 의도적으로 값이 없음을 가리키는 '객체' 타입의 null과

   아직 어떤 값도 할당되지않은 변수임을 나타내는 '정의되지 않음' 객체인 undefined 이 있다.

 

6. 변수 (Variables)

 - 변수 선언시 사용할 수 있는 키워드는 let, const, var 키워드가 있다.

  • let

    • 블록 유효 범위 변수를 선언할 수 있다.

for(let index = 0; index < 10; index++ )
{
    console.log(index);
}
// console.log(index); -> Error
  • const

    • 값이 변경되지 않는 변수를 선언할 수 있다.

const pi = 3.141592
// pi = 22; -> Error
  • var

    • 가장 일반적인 변수 선언 키워드.

    • let, const가 가지는 제한을 갖지 않는다.

for(var index = 0; index < 10; index++)
{
    console.log(index);
}
console.log(index);

 

7. 연산자 (Operators)

  • 이중 등호(==)
    - 서로 다른 타입을 줄 경우 강제로 타입 변환을 수행한다. 따라서 주의해야 한다.

console.log(123 == '123'); // true
console.log(1 == true); // true
  • 삼중 등호(===)

    - 강제 타입 변환을 하지 않고 비교하기 위해서는 삼중 등호(===)를 사용한다.

console.log(123 === '123'); // false
console.log(1 === true); // false

 

8. 제어 구조

  • for-of 와 for-in

    - for-in : 객체의 모든 열거 가능한 속성에 대해 반복. (key 값에는 접근 가능, value는 접근 불가)- for-of : [Symbol.iterator] 속성을 가지는 컬렉션 전용

 

Object.prototype.objCustom = function () {};
Array.prototype.arrCustom = function () {};

var iterable = [3, 5, 7];
iterable.foo = "hello";
console.log(iterable.foo);

console.log('-------------');

for (var key in iterable) {
  console.log(key); // 0, 1, 2, "foo", "arrCustom", "objCustom"
}

console.log('-------------');

for (var value of iterable) {
  console.log(value); // 3, 5, 7
}
  • foreach

    - 오직 Array 객체에서만 사용가능한 메서드였지만, ES6 부터 Map, Set 등 여러가지에도 추가 지원됨)

var items = [1,2,3,4];

items.forEach(item => {
    console.log(item);
});

 

9. 객체 (Objects)

 - JavaScript 객체는 key-value의 모임이다. 따라서 다음과 비슷하다.

  • Python의 Dictionaries

  • Perl과 Ruby의 Hashes

  • C와 C++의 Hash tables

  • Java의 HashMaps

  • PHP의 Associative arrays

 - JavaScript의 대부분은 객체로 취급되기 때문에 기본적으로 해쉬 테이블을 검색하는데 좋은 성능을 보임.

 - 값은 객체를 포함하여 모든 것이 될 수 있지만, Key(이름)은 문자열 이다.

// 빈 객체를 생성하는 방법
var object = new Object();
// or
var obj = {};

 - 두 번째 방법은 객체 리터럴 구문이라고 부르며 JSON 구문으로 나타내기 좋다.

var object = {
    name : "Matagi",
    for : "max",
    details: {
        color : "red",
        size : 12
    }
}

console.log(object["details"]["size"]);

 - 객체 프로토타입(Person)과 프로토타입의 인스턴스(you)를 생성

function Person(name, age) {
    this.name = name;
    this.age = age;
}

// 객체 정의
var you = new Person("matagi", 28);
console.log(you.name + " age " + you.age);

 

10. 배열 (Arrays)

 - 배열의 생성 및 length

var array = new Array();
array[0] = "dog";
array[1] = "cat";
array[2] = "human";
console.log(array.length);

var overSizeArr = new Array();
overSizeArr[0] = "index_1"
overSizeArr[100] = "index_2"
console.log(overSizeArr.length);
console.log(typeof(overSizeArr[99])); // undefined

 - forEach를 사용한 배열 요소 출력.

array.forEach(item => {
    console.log(item);
});

 

11. 함수 (Functions)

 - 함수의 가장 기본적인 예

 - Return이 없다면 undefined를 반환한다.

function add(x,y) {
    var total = x+y;
    return total;
}

 - arguments 를 통해, 매개 변수로 넘겨진 모든 값을 사용할 수 있다.

function loop()
{
    for(let item of arguments)
    {
        console.log(item);
    }
}

loop(2,3,4,5,6);
  •  Rest 파라미터 구문

    - 정해지지 않은 인수를 배열로 나타낼 수 있게 한다.

function loop(...params)
{
    for(let item of params)
    {
        console.log(item);
    }
}

loop(2,3,4,5,6);
  • 익명 함수

    - 익명 함수 사용의 예

var loop = function()
{
    for(let i = 0; i < 10; i++)
    {
        console.log(i);
    }
}

loop();
  • 즉시 실행 함수 표현(IIFEs)

var charsInBody = (function counter(elm) {
  if (elm.nodeType == 3) { // TEXT_NODE
    return elm.nodeValue.length;
  }
  var count = 0;
  for (var i = 0, child; child = elm.childNodes[i]; i++) {
    count += counter(child);
  }
  return count;
})(document.body);

 

12. 사용자 정의 객체

 - JavaScript는 프로토타입 기반언어로 C++이나 Java에서 사용되는 Class 구문이 없다.

   따라서 JavaScript는 function을 class로 사용한다.

 - Person.prototype은 모든 Person 인스턴스들간에 공유되는 객체.

   Person 객체의 설정되지 않은 속성에 접근을 시도할 때마다 그것의 대체 용도로

   JavaScript는 Person.prototype에서 그 속성이 존재하는지 살펴본다.

function Person(first, last)
{   
    this.first = first;
    this.last = last;
}

Person.prototype.fullName = function(){
    return this.first + ' ' + this.last;
}

Person.prototype.fullNameReversed = function(){
    return this.last + ' ' + this.first;
}

var person = new Person('Hong', 'Gil Dong');
console.log(person.fullName());
console.log(person.fullNameReversed());

 

13. 내장 함수 (Inner functions)

 - 좀 더 유지관리가 쉬운 코드를 작성하고자 할 때.

 - 한 개 혹은 두 개의 정도의 함수에서만 호출되며 전체 코드 중 다른 부분에서는 사용처가 없는 함수일 경우.

function parentFunc() {
    var a = 1;

    function nestedFunc() {
        var b = 4; // parentFunc은 사용할 수 없는 변수
        return a + b;
    }
    return nestedFunc();  // 5
}

 

14. 클로져 (Closures)

 - JavaScript 함수가 실행될 때는 언제나 '범위' 객체가 생성되어 해당 함수 내에서 생성된 지역 변수를 저장하고 있다.

   이것은 모든 전역 변수와 함수가 들어있는 전역 객체와 비슷하지만 두 가지 차이점이 있다.

 - 첫 번째로, 함수가 실행될 때마다 새로운 범위 객체가 생성된다.

   두 번째로, (브라우저에서 Window로 접근가능한) 전역 객체와 달리 범위 객체는 JavaScript 코드에서

   직접적으로 접근할 수 없다.

function makeAdder(a) {
    return function(b) {
      return a + b;
    };
  }
  var add5 = makeAdder(5);
  var add20 = makeAdder(20);
  console.log(add5(6)); // 11
  console.log(add20(7)); // 20

 - 위의 예에서 makeAdder()가 호출되면, 범위 객체는 makeAdder() 함수에 매개변수로 넘겨진 하나의 속성 a를

   가진 상태로 생성된다.

   일반적으로 JavaScript의 GC가 이 때 makeAdder()에 의해 생성된 범위 객체를 청소해야겠지만,

   리턴된 함수가 여전히 범위 객체를 참조하고 있다.

   결과적으로 범위 객체는 makeAdder()에 의해 리턴된 함수 객체가 더는 참조되지 않을 때까지 정리되지 않는다.

 

  • 예제

    - el을 참조하면 의도와는 달리 익명 내부 함수 때문에 생성된 클로져 내에 붙잡혀 있는다.

function addHandler() {
    var el = document.getElementById('el');
    el.onclick = function() {
        this.style.backgroundColor = 'red';
    }
}

 

  • 해결 방법 - 1

    - 가장 간단하게 해결할 수 있는 방법은 아래와 같다. (순환 참조 고리를 끊음)
function addHandler() {
    var el = document.getElementById('el');
    el.onclick = function() {
        this.style.backgroundColor = 'red';
    }
    el = null;
}
  • 해결 방법 - 2

    - 클로져에 의해 발생된 순환 참조 고리를 끊기 위한 하나의 요령은 또 다른 클로져를 추가하는 것.

    - 내부 함수는 실행되고 바로 사라지므로, clickHandler와 함께 생성된 클로져로부터 그 내용을 숨김
function addHandler() {
    var clickHandler = function() {
        this.style.backgroundColor = 'red';
    }
    (function() {
        var el = document.getElementById('el');
        el.onclick = clickHandler;
    })();
}
  • 해결 방법 - 3

    - 또 다른 좋은 요령은 window.onunload 이벤트가 발생하는 동안 순환 참조를 끊는 것.

    - 많은 이벤트 라이브러리가 이렇게 동작한다.

    - 주의할 것은 Firefox 1.5의 bfcache를 비활성하게 되므로,

      별 다른 이유가 없다면 firefox에서 unload listener를 등록해서는 안된다.