IT_Programming/JavaScript

자바스크립트 완벽가이드 - 5.10 기타 연산자들

JJun ™ 2010. 7. 4. 20:12


1. 조건부 연산자(?:)

 

조건부 연산자는 자바스크립트의 유일한 3항 연산자(피연산자가 세 개)이며, 때로는 그 자체로 3항 연산자라고 불리기도 한다. 이 연산자는 종종 ?: 라고 표시되지만 이는 실제 코드에서 보게 되는 것과 좀 다르다.

 

이 연산자의 피연산자는 셋이기 때문에, 첫 번째 피연산자는 ? 앞에 위치하고 두 번째는 ?와 : 사이에 위치하며 세번째는 : 뒤에 위치한다. 실제 사용 예는 다음과 같다.

 

x > 0 ? x*y : -x*y


조건부 연산자의 첫 번째 피연산자는 불리언 값이어야 한다(또는 불리언 값으로 변환될 수 있어야 한다).

이 불리언 값은 보통 비교 표현식의 결과인 경우가 많다. 두 번째와 세 번째 피연산자는 아무 값이나 될 수

있다. 조건부 연산자가 반환하는 값은 첫 번째 피연산자의 불리언 값에 의해 결정된다. 그 값이 true이면

조건부 표현식의 값은 두 번째 피연산자의 값이 된다. 첫 번째 피연산자의 값이 false이면 조건부 표현식의

값은 세 번째 피연산자의 값이 된다.


물론 if 문을 사용해서 비슷한 결과를 얻을 수 있지만, ?: 연산자는 종종 편리하고 간결한 문법을 제공하곤

한다. 다음 예에서 전형적이 사용법을 볼 수 있다. 어떤 변수가 정의되어 있는지 확인한 후, 정의되어 있다면

그 변수를 사용하고 그렇지 않으면 디폴트 값을 사용하는 예다.

greeting = "hello " + (username != null ? username : "there");


위 예는 다음에 나오는 if 문과 동등하지만 훨씬 간결하다.

greeting = "hello ";
if (username != null)
greeting += username;
else
greeting += "there";

 

 

 

 

2. typeof 연산자

 

typeof 연산자는 단일 피연산자 앞에 위치하는 단항 연산자로, 피 연산자는 아무 타입이라도 무방하다.

이 연산자의 값은 피연산자의 데이터 타입을 가리키는 문자열이다.


주어진 피연산자가 숫자, 문자열, 또는 불리언 값일 경우 typeof 연산자의 결과도 그에 따라 "number", "string" 또는 "boolean"이 된다. 객체, 배열, 그리고(놀랍게도) null에 대해서는 결과로 "object"를 반환한다. 함수 타입의 피연산자에 대해서는 "function"을, 그리고 정의되지 않은 피연산자에 대해서는 "undefined"를

반환한다.


피연산자로 Number, String 또는 Boolean 포장(wrapper) 객체가 주어지면 typeof의 결과는 "object"가 된다. 또한Date나 RegExp 객체에 대한 결과도 "object"가 된다. 코어 자바스크립트에 속하지 않은 객체가 피연산자로 주어질 경우, 해당 자바스크립트가 내장된 환경에서 제공되는 값, 즉 각각의 구현에 종속적인 값을 typeof의 결과로 반환한다. 하지만 클라이언트 측 자바스크립트에서는, 모든 코어 객체들과 마찬가지로 모든 클라이언트 측 객체에 대한 typeof의 결과는 "object"가 된다.

 

아마도 여러분은 다음의 표현식처럼 typeof를 사용할 것이다.

typeof i
(typeof value == "string") ? "'" + value + "'" : value


typeof의 피연산자를 괄호로 둘러쌀 수도 있는데,

이렇게 하면 typeof가 연산자 키워드라기보단 마치 함수 이름처럼 보이곤 한다.

typeof(i)

 

typeof는 모든 객체와 배열 타입에 대해 "object" 결과를 반환하기 때문에 오직 객체를 다른 기본 타입들과

구분하는 용도로만 쓸 수 있다. 한 객체와 다른 객체를 구분하기 위해서는 instanceof 연산자(5.5.3항)나 constructor 프로퍼티(3부의 코어자바스크립트 레퍼런스의 Object.constructor 항목을 참조하라)와 같은

다른 기법을 사용해야 한다.


typeof 연산자는 ECMAScript v1 명세에 정의되었으며 자바스크립트 1.1과 이후 버전에서 구현되어 있다.

 

 

 

3. 객체 생성 - new 연산자

 

new 연산자는 새로운 객체를 생성하고 이를 초기화하기 위한 생성자 함수를 호출한다.

new 연산자는 단항 연산자로 호출 앞에 위치한다.

 

문법은 다음과 같다.

new constructor(arguments)


constructor는 반드시 생성자 함수로 평가되는 표현식이어야 하며, 이에 따르는 전달인자는 괄호로 감싸야

한다. 전달인자는 없을 수도 있으나 2개 이상일 때는 쉼표로 구분해야 한다. new 연산자에만 해당하는 특수한 경우로, 자바스크립트에서는 함수 호출에 전달인자가 없을 경우 괄호를 생략할 수 있는 간단한 문법을 지원한다. 디음에서 new 연산자를 사용하는 몇 가지 예를 살펴보자.

o = new Object;  // 선택적으로 쓸 수 있는 괄호가 여기서는 생략 되었다.
d = new Date();  // 현재 시각을 나타내는 Date 객체를 반환한다.
c = new Rectangle(3.0, 4.0, 1.5, 2.75);  // Rectangle 클래스의 객체를 생성한다.
obj[i] = new constructors[i]();

 

new 연산자가 처음 생성하는 객체에는 아무런 프로퍼티도 정의되어 있지 않다. 객체 생성 이후 new 연산자는 지정된 생성자 함수를 호출하여 명시된 전달인자들을 전달하고 또한 방금 생성된 새 객체도 this 키워드를 통해 전달한다. 생성자 함수는 이 this 키워드를 사용하여 나름대로의 방법으로 새 객체를 초기화한다.

new 연산자와 this 키워드, 그리고 생성자 함수는 7장에서 더 배울 것이다.

또한 new 연산자는 Array() 문법을 사용하여 배열도 생성할 수 있다.

객체와 배열을 생성하고 다루는 방법도 7장에서 더 접할 수 있을 것이다.

 

 

 

4. delete 연산자

 

delete는 단항 연산자이며, 피연산자로 지정된 객체 프로퍼티, 배열 원소 또는 변수의 삭제를 시도한다.[각주:1] 피연산자가 성공적으로 삭제되었을 경우 true를 반환하고, 삭제될 수 없는 경우 false를 반환한다. 모든 변수나 프로퍼티는 삭제할 수는 없다. 몇몇 내장 코어 프로퍼티나 클라이언트 측 프로퍼티는 삭제하려 해도 소용이 없으며, 사용자가 var 문으로 정의한 변수들도 삭제할 수 없다. 존재하지 않는 프로퍼티에 대해 delete를 호출할 경우 true가 반환된다. (심지어, ECMAScript 표준에 따르면 delete의 피연산자가 프로퍼티, 배열 원소 또는 변수가 아닐 경우에도 true를 반환한다고 명시되어 있다.)

 

이 연산자를 사용하는 예는 다음과 같다.

var o = {x:1, y:2};    // 변수를 정의하고 객체로 초기화한다.
delete o.x;             // 객체 프로퍼티 중 하나를 삭제한다. true가 반환된다.
typeof o.x;             // 존재하지 않는 프로퍼티. "undefined"가 반한된다.
delete o.x;             // 존재하지 않는 프로퍼티를 삭제하려 한다. true가 반환된다.
delete o;               // 선언된 변수는 삭제할 수 없다. false가 반환된다.
delete 1;                // 정수도 삭제할 수 없다. true가 반환된다.
x = 1;                    // var 키워드를 사용하지 않고 암묵적으로 변수를 선언한다.
delete x;               // 이와 같은 종류의 변수는 삭제할 수 있다. true가 반환된다.
x;                         // 런타임 에러. x는 정의되지 않았다.


삭제된 프로퍼티나 변수, 배열 원소는 단순시 undefined값으로 설정된 것이 아니라는 것을 주의하라.

어떤 프로퍼티가 삭제되면 그 프로퍼티는 더이상 존재하지 않는다. 4.3.2항의 관련 설명을 참조하라.
한 가지 중요한 점은, delete가 영향을 미치는 것은 오직 프로퍼티 뿐이며 해당 프로퍼티가 참조하고 있던

객체는 무관하다는 것이다. 다음의 코드를 살펴보자.

var my = new Object();        // 'my'라는 이름의 객체를 생성한다.
my.hire = new Date();          // my.hire는 Date 객체를 참조한다.
my.fire = my.hire;                // my.fire도 동일한 객체를 참조한다.
delete my.hire;                    // hire 속성이 삭제되었다. true가 반환된다.
document.write(my.fire);      // 하지만 my.fire는 여전히 Date 객체를 참조하고 있다.

 

         1) 여러분이 C++ 프로그래머라면 자바스크립트의 delete 연산자는 C++의 delete 연산자와 전혀 닮지

             않았다는 것을 발견할 것이다. 자바스크립트의 메모리 해제는 가비지 컬렉션에 의해 자동으로

             관리되기 때문에 여러분은 메모리를 직접 해제하는 일에 신결 씅 필요가 전혀 없다.

             따라서 C++방식처럼 객체 전체를 삭제하는 용도의 delete는 필요가 없다. [본문으로]

 

 

 

5. void 연산자

 

void는 단일 피연산자 앞에 쓰이는 단항 연산자로, 피연산자의 타입은 아무 타입이라도 관계없다.

이 연산자를 쓰는 목적은 좀 이례적이다. 이 연산자는 피연산자의 값을 무시하고 undefined를 반환한다.

이 연산자의 가장 일반적인 사용처는 클라이언트 측의 javascript: URL이다.

 

이 URL은 여러분이 어떤 자바스크립트 표현식의 부수 효과를 평가할 때, 브라우저에 평가된 값을

표시하지 않으면서 표현식을 평가할 수 있게 해준다.

예를 들면 다음과 같이 HTML태그 안에 void 연산자를 쓸 수 있다.

<a href="javascript:void window.open();">Open New Window</a>

 

void 연산자의 또 다른 목적은 의도적으로 undefined 값을 만들어내기 위함이다.

void는 ECMAScript v1에서 명시되었으며 자바스크립트 1.1에서 구현되었다.

그러나 전역의 undefined 프로퍼티는 ECMAScript v3에서 명시되었으며 자바스크립트 1.5에서 구현되었다.

따라서 하위 호환성을 위해서라면 undefined 프로퍼티에 의존하는 대신 void 0과 같은 표현식을 쓰는 것이

유용할 수 있다.

 

 

 

6. 쉼표 연산자

 

쉼표 연산자는 간단하다.

이 연산자는 왼쪽의 전달인자를 평가하고 오른쪽의 전달인자를 평가한 후, 오른쪽 전달인자의 값을 반환한다.

 

따라서 다음의 코드는,

i=0, j=1, k=2;


2로 평가되며, 기본적으로 아래 코드와 동일하다.

i = 0;
j = 1;
k = 2;

 

이 기묘한 연산자는 몇몇 제한적인 상황에서만 요긴하게 쓰인다.

무엇보다 요긴한 곳은, 하나의 표현식만이 허락되는 상황에서 부수 효과가 일어나는 다수의 개별 표현식들을 평가해야 할 경우다 .실전에서 쉼표 연산자가 실제로 사용되는 곳은 for 루프문과 함께 쓰이는 경우뿐인데,

이는 6장에서 설명하겠다.

 

 

 

7. 배열과 객체 접근 연산자

 

3장에서 간단히 접한 바와 같이, 배열 원소에 접근하는 데에는 대괄호([])를 사용하면 된다.

또 객체의 원소에 접근하는 데에는 마침표(.)를 사용하면 된다. []와 마침표(.) 모두 자바스크립트 연산자로

취급된다. 연산자는 좌변 피연산자로 객체를 받으며, 우변 피연산자로는 식별자(프로퍼티 이름)를 받는다.

우변 피연산자는 문자열이나 문자열을 포함하는 변수가 되어서는 안 된다. 우변 피연산자는 어떤 종류의

따옴표도 쓰지 않은 상태로 프로퍼티나 메서드의 이름에 해당하는 리터럴이어야 한다.

 

아래에 몇 가지 예가 있다.

document.lastModified
navigator.appName
frames[0].length
document.write("hello world")


만일 객체에 지정된 프로퍼티가 존재하지 않아도 자바스크립트는 에러를 일으키지 않는다.

그 대신 그 표현식의 값으로 단순히 undefined를 반환할 뿐이다.


대부분의 연산자들은 보통 어떤 피연산자에 대해서나 임의의 표현식을 허용한다.

물론 그 피연산자의 타입과 맞을 경우에 한해서다. 하지만 마침표(.) 연산자는 예외다.

우변 피연산자에는 반드시 식별자가 와야 하며 그 이외에는 아무것도 허락되지 않는다.


[] 연산자는 배열 원소에 접근할 수 있게 해준다. 또한 [] 연산자로 객체 프로퍼티에도 접근할 수 있는데,

여기서는 마침표(.) 연산자처럼 우변 피연산자에 대한 제한은 없다. 첫 번째 피연산자(왼쪽 대괄호 앞에

나오는 것)가 배열을 참조할 경우, 두 번째 피연산자(대괄호 사이에 있는 것)는 정수로 평가되는 표현식이어야 한다. 예를 들면 다음과 같다.

frames[1]
document.forms[i + j]
document.forms[i].elements[j++]


[] 연산자의 첫 번째 피연산자가 객체를 참조할 경우, 두 번째 피연산자는 그 객체의 프로퍼티 이름에 해당하는 문자열로 평가되는 표현식이어야 한다. 이 경우 두 번째 피연산자는 문자열이지 식별자가 아니다.

이 문자열은 따옴표로 묶인 상수이거나, 문자열을 참조하는 변수나 표현식이어야 한다.

 

예를 들면 다음과 같다.

document["lastModified"]
frames[0]['length']
data["val" + i]


[]는 보통 배열의 원소에 접근하는데 사용된다. 객체 프로퍼티에 접근하는 용도로는 마침표(.) 연산자보다

불편한데, 그 이유는 프로퍼티 이름을 따옴표로 인용해야 하기 때문이다. 그러나 객체가 연관배열로 사용될 경우 프로퍼티 이름이 동적으로 생성되며, 따라서 마침표(.) 연산자를 사용할 수 없다.

 

이 경우에는 오직 [] 연산자만 사용할 수 있다. 여러분이 6장에서 소개할 for/in 루프를 쓰다 보면 이 같은

경우를 쉽게 만날 것이다. 예를 들어 다음의 자바스크립트 코드는 for/in 루프와 [] 연산자를 사용해서

객체 o의 모든 프로퍼티 이름과 값을 출력한다.

for (f in o) {
document.wirte('0.' + f + ' = ' + o[f];
document.write('<br>');
}

 

 

 

8. 함수 호출 연산자

 

() 연산자는 자바스크립트에서 함수 호출에 사용된다.

이 연산자는 좀 이례적인데, 왜냐하면 피연산자의 개수가 정해져 있지 않기 때문이다.

 

첫 번째 연산자는 언제나 함수 이름 또는 함수 이름을 참조하는 표현이어야 한다.

이어서 왼쪽 괄호가 따라오고, 임의 개수의 피연산자들이 추가될 수 있다.

이들 피연산자는 임의의 표현식이 될 수 있으며 서로 다른 피연산자들은 쉼표로 구분된다.

 

 마지막 피연산자 뒤에는 오른쪽 괄호가 따라온다.

() 연산자는 각각의 피연산자를 평가한 후 첫 번째 피연산자로 지정된 함수를 호출하고,

나머지 피연산자들의 값을 함수의 전달인자로 넘긴다.

 

예를 들면 다음과 같다.

 

document.close()
Math.sin(x)
alert!!("Welcome " + name);
Date.UTC(2000, 11, 31, 23, 59, 59)
funcs[i].f(funcs[i].args[0], funcs[i].args[1])