자바스크립트에서 문자열은 문자 배열과 겉모습은 닮았지만 배열이 아니다.

const str = "foo";
const arr = ["f", "o", "o"];

str[1]  // "o"
arr[1]  // "o"

 

문자열과 문자 배열의 차이 중 하나로 위의 코드와 같이 문자열의 특정 문자를 접근할 때

배열과 같이 a[1]이라고 접근하는 것은 모든 자바스크립트 버전에서 유효한 것은 아니다.

일부 구버전 IE에서는 undefined를 반환한다.

정확하게는 a.charAt(1) 으로 접근해야한다.

 

문자열과 문자 배열의 가장 중요한 차이는 

문자열은 불변 값이지만, 배열은 가변 값이라는 것이다.

 

문자열은 불변 값이므로 문자열 메서드는 해당 문자열 내용을 변경하지 않고

항상 변경된 새로운 문자열을 생성해 반환한다.

즉 원래의 문자열 값은 변하지 않는 것이다.

 

반면 대부분의 배열 메서드는 원래의 배열 값을 변경한다.

const bigStr = str.toUpperCase();

str; // "foo" 원래 값이 변하지 않음
bigStr; // "FOO"

arr.push("!");
arr;  // ["f", "o", "o", "!"] 원래 값이 변함

 

배열 메서드 중에서도 원래 배열의 값을 변화시키지 않는 

일부 불변 배열 메서드는 문자열이 빌려서 사용할 수 있다.

str.join;  // undefined
str.map;  //undefined

const joinStr = Array.prototype.join.call(a, "-");
const mapStr = Array.prototype.map.call(a, c => 
               c.toUpperCaser() + ".")
               .join("");

joinStr;  // "f-o-o"
mapStr;  // "F.O.O."

 

만약 가변 배열 메서드를 사용하고 싶으면

문자열을 배열로 바꾸고 원하는 작업을 수행한 후 다시 문자열로 되돌리는 방법이 있다.

const reverseStr = str
    // str을 배열로 분해
    .split("")
    // 문자 배열의 순서를 거꾸로 뒤집음
    .reverse()
    // 문자 배열을 합쳐 다시 문자열로 만듬
    .join("");

reverseStr; // oof

 

만약 문자열 자체에 어떤 작업을 빈번하게 수행하는 경우라면

문자열을 배열로 취급하여 작업하는 것이 효율적일 수 있다.

 

https://github.com/getify/You-Dont-Know-JS

 

getify/You-Dont-Know-JS

A book series on JavaScript. @YDKJS on twitter. Contribute to getify/You-Dont-Know-JS development by creating an account on GitHub.

github.com

'Javascript' 카테고리의 다른 글

자바스크립트 배열  (0) 2019.12.29
선언되지 않은 변수  (0) 2019.12.14
자바스크립트 내장 타입  (0) 2019.12.14

자바스크립트 배열은 미리 크기를 정하지 않고 선언할 수 있으며, 어떤 타입의 값도 넣을 수 있다.

const arr = [];

arr.length;  // 0

arr[0] = 1;
arr[1] = "str";
arr[2] = [1,2,3];

arr.length;  // 3

 

만약 다음과 같이 중간을 건너뛰어 빈 구멍이 생긴다면

구멍의 값은 undefined가 될 것 같지만, 명시적으로 undefined를 세팅한 것과 같지 않으므로 주의한다.

const arr = [];

arr[0] = 1;
// arr[1]을 건너뜀
arr[2] = undefined;

arr[1]  // undefined
arr;  // [1, empty, undefined]

 

앞서 포스팅에서 언급했다시피 배열은 객체이다.

객체이기 때문에 배열에도 키/프로퍼티 문자열을 추가할 수 있지만, 주의해야할 점이 몇가지 있다.

 

첫번째는 문자열 키를 추가하면 배열의 length는 증가하지 않는다는 점이다.

const arr = [];

arr[0] = 1;
arr["idx"] = 2;

arr;  // [1, "idx": 2]

arr.length;  // 1
arr["idx"];  // 2
arr.idx;  // 2

 

두번째는 키로 넣은 문자열이 표준 10진수 숫자로 타입 변환이 되면,

마치 문자열 키가 아닌 숫자 키를 사용한 것과 같은 결과가 된다는 점이다.

const arr = [];
arr["13"] = 13;

arr.length;  // 14

 

따라서 배열에 문자열 타입의 키/프로퍼티를 사용하는 것은 추천하지 않는다.

문자열 타입의 키/프로퍼티를 사용해야한다면 객체를 사용하는 것을 추천한다.

 

https://github.com/getify/You-Dont-Know-JS/

 

getify/You-Dont-Know-JS

A book series on JavaScript. @YDKJS on twitter. Contribute to getify/You-Dont-Know-JS development by creating an account on GitHub.

github.com

'Javascript' 카테고리의 다른 글

자바스크립트 문자열  (0) 2019.12.29
선언되지 않은 변수  (0) 2019.12.14
자바스크립트 내장 타입  (0) 2019.12.14

1. 값이 없는 vs 선언되지 않은

값이 없는 변수의 값은 undefined이며, typeof의 결과는 "undefined"이다.

 

undefined와 undeclared는 전혀 다른 개념이다.

 

undefined는 접근 가능한 스코프에 변수가 선언되었으나 현재 아무런 값도 할당되지 않은 상태를 가리키는 반면,

undeclared는 접근 가능한 스코프에 변수 자체가 선언조차 되지 않은 상태를 가리킨다.

let a;

console.log(a); // undefined
console.log(b); // ReferenceError: b is not defined

 

문제는 선언되지 않는 변수에 typeof를 해도 오류 처리를 하지 않는다.

선언되었지만 값을 할당하지 않은 변수도, 선언되지 않은 변수도 모두 typeof의 결과값은 undefined이다.

let a;

typeof a; // "undefined"
typeof b; // "undefined"

 

2. 선언되지 않는 변수

선언되지 않은 변수를 처리하는 typeof의 방식은

여러 스크립트 파일의 변수들이 전역 네임 스페이스를 공유할 때 유용하다.

[func.js]
function sum(a, b) {
  return a + b;
}

function product(a, b) {
  return a * b;
}

export { sum, product }
[app.js]
import {product, sum} from 'func';

console.log(product(1,2)); // 2
console.log(sum(1,2)); // 3

// 이 경우 DEBUG라는 변수가 없으므로 에러 발생!
if (DEBUG) {
  console.log("디버깅을 시작합니다.");
}

// 이렇게 해야 안전하게 존재 여부를 체크할 수 있다.
if (typeof DEBUG !== "undefined") {
  console.log("디버깅을 시작합니다.");
}

 

typeof 없이 전역 변수를 체크하는 다른 방법은

전역 변수가 모두 전역 객체(브라우저는 window)의 프로퍼티라는 점을 이용하는 것이다.

 

선언되지 않은 변수 때와는 달리 어떤 객체의 프로퍼티를 접근할 때는 

그 프로퍼티가 존재하지 않아도 ReferenceError가 나지 않는다.

// DEBUG가 없으면 에러가 남
if (DEBUG) {
  console.log("디버깅을 시작합니다.");
}

// DEBUG가 없어도 에러가 나지 않음
if (window.DEBUG) {
  console.log("디버깅을 시작합니다.");
 }

 

하지만 다중 자바스크립트 환경에서는 전역 객체가 window가 아닐 수 있으므로 

window 객체를 통한 전역 변수 참조는 가급적 삼가는 것이 좋다.

 

typeof는 전역변수를 사용하지 않을 때도 유용하다.

(function() {
  function test(a, b) {
    return a + b;
  }
  
  function doSomething() {
    const func = 
      (typeof test !== "undefined") ?
      test :
      function(a, b) { return a - b; };
      
    console.log(func(1,2));
  }
  
  doSomething();
})();

test는 전역 변수가 아니지만 8~10번째 줄에서 typeof로 존재 여부를 확인하고 있다.

위 코드에서는 전역변수와 같이 체크 용도로 사용할 만한 객체가 없기 때문에 typeof가 꽤 요긴하다.

 

또는 다음과 같이 명시적으로 나타낼 수도 있다.

(function() {
  function test(a, b) {
    return a + b;
  }
  
  function doSomething() {
    const func = test ||
      function(a, b) { return a - b; };
      
    console.log(func(1,2));
  }
  
  doSomething();
})();

 

https://github.com/getify/You-Dont-Know-JS

 

getify/You-Dont-Know-JS

A book series on JavaScript. @YDKJS on twitter. Contribute to getify/You-Dont-Know-JS development by creating an account on GitHub.

github.com

'Javascript' 카테고리의 다른 글

자바스크립트 문자열  (0) 2019.12.29
자바스크립트 배열  (0) 2019.12.29
자바스크립트 내장 타입  (0) 2019.12.14

자바스크립트에서 타입이란, 자바스크립트 엔진과 개발자 모두에게

어떤 값을 다른 값과 분별할 수 있는 고유한 내부 특성의 집합이다.

 

자바스크립트에는 다음 7가지 내장 타입이 있다.

  • null

  • undefined

  • boolean

  • number

  • string

  • object

  • symbol

1. 원시 타입과 참조 타입

자바스크립트에서는 원시 타입(primitive type) 참조 타입(reference type)이라는 두 가지 자료형을 제공한다.

object를 제외한 나머지 타입들은 모두 원시 타입이다.

원시 타입 데이터는 변수에 할당될 때 메모리 상에 고정된 크기로 저장되고 해당 변수가 원시 데이터 값을 보관한다.

let x = 100; // 원시 타입 데이터를 선언
let y = x; // 값을 새 변수에 복사
x = 99; // x의 값을 변경, y의 값은 변경되지 않음
console.log(y); // 100 

 

object는 참조 타입이다.

array나 function 같은 것은 object에 속한다.

 

참조 타입 데이터는 크기가 정해져 있지 않고 변수에 할당될 때 값이 직접 해당 변수에 저장될 수 없으며,

변수에는 데이터에 대한 참조만 저장된다. 참조는 참조 타입 데이터의 주소이지 해당 데이터의 값이 아니다.

let x = { count: 100 };  // 참조 타입 데이터를 선언
let y = x;  // 참조를 새 변수에 복사
x.count = 99;  // 참조 타입 데이터를 변경, y는 동일한 참조를 담고 있음
console.log(y.count);  // 99

 

2. 내장 타입

값 타입은 typeof 연산자로 알 수 있다.

typeof undefined  // "undefined"
typeof true  // "boolean"
typeof 42  // "number"
typeof "42"  // "string"
typeof { apple : 30 }  // "object"
typeof Symbol()  // "symbol"

 

단 null에 대한 typeof 연산 결과는 조금 다르다.

타입이 null이 아니라 object로 나온다.

typeof null  // "object"

 

따라서 타입으로 null 값을 정확히 확인하려면

다음과 같이 falsy값을 확인하는 조건이 하나 더 필요하다.

const a = null;
(!a && typeof a === "object");  // true

 

typeof는 이 외에도 "function"이라는 타입을 반환한다.

typeof function foo(){}  // "function"

 

위 결과를 보면 function이 마치 또 다른 내장 타입같지만,

위에서 언급했듯 function은 object의 하위 타입이다.

 

함수는 객체이기 때문에 함수에 프로퍼티를 둘 수 있다.

함수에 선언된 인자 개수는 함수 객체의 length 프로퍼티로 알 수 있다.

function foo(a, b){}
foo.length; // 2

 

배열 역시 object의 하위 타입이다.

typeof [1,2,3] // "object"

 

3. 값은 타입을 가진다

값에는 타입이 있지만, 변수에는 따로 타입이 없다.

변수는 언제라도, 어떤 형태의 값이라도 가질 수 있다.

 

자바스크립트는 '타입 강제'를 하지 않기 때문에, 변숫값이 처음에 할당된 값과 동일한 타입일 필요가 없다.

숫자를 넣었다가 나중에 문자열을 넣어도 상관없다.

 

변수에 typeof 연산자를 대어 보는 건 실제로 "이 변수에 들어있는 값의 타입은 무엇이니?"라고 묻는 것이다.

let a = 42;
typeof a; // number

a = true;
typeof a; // boolean

 

 

https://github.com/getify/You-Dont-Know-JS

 

getify/You-Dont-Know-JS

A book series on JavaScript. @YDKJS on twitter. Contribute to getify/You-Dont-Know-JS development by creating an account on GitHub.

github.com

 

'Javascript' 카테고리의 다른 글

자바스크립트 문자열  (0) 2019.12.29
자바스크립트 배열  (0) 2019.12.29
선언되지 않은 변수  (0) 2019.12.14

+ Recent posts