본문 바로가기

Development/Coding

유능한 C# 개발자가 착각하는 나쁜 자바스크립트 습관. Part 2

http://enterprisejquery.com/
How Good C# Habits can Encourage Bad JavaScript Habits 라는 제목으로 올려진 연재글 발.역.

* Java 개발자나 C# 개발자들이 자바스크립트를 코딩할 때 자주 쓰이는 잘못된 방법을 예를 통해 설명하고 옳은 방법(자바스크립트 다운 방법)을 제시해주고 있는 좋은 글이네요.


지난 포스팅 내용
  1. Having Variables & Functions in Global Scope
  2. Not Declaring Arrays & Objects Correctly


파트 2

Introduction

지난 게시물에 이어 개발자들이 자바스크립트를 코딩할 때 애메한 상황에서 잘못 이해하고 있는 몇가지 내용을 점검해보도록 하자.


3. Not Understanding False-y Values

자바스크립트의 우항의 거짓 대입문은 C# 과 다르게 작동하고 있다네.

if 구문 참인 식에 대해 블럭 안의 구문을 실행하고 거짓인 식에 대해 else 블럭을 실행하거나 if 문을 종료하죠. 어떤 경우에는 이 거짓인 식에 대해 판단하기가 애메한 경우가 있다는 것이지.

거짓인 식의 결과는 다음과 같음.

false
null
undefined
"" (empty string)
0
NaN (not a number)

이 외의 다른 값들은 모두 참! 이야. (모든 객체와 "0" 이라는 문자, "false"라는 문자열도 마찬가지)

그외의 케이스에 대해 조금 더 있다가 살펴보자고.


4. Not Testing & Setting Default Values Correctly

비교문에서 널을 체크하거나 디폴트 값을 세팅할 때 보면 자바스크립트 개발자가 아닌 티가 좀 날거야.

- 널 체크하는 법

보통 시샵에서 변수 사용을 위해 널체크는 기본적으로 고려하는 사항이자나. 자바스크립트에서는 그게 함정이 될 수도 있다는 것이야. 코드를 보자

// C# example. Don't do this in JavaScript
if ( someString != null &&
    someString.length > 0 ) {
    //Do something here...
}

물론 닷넷에서 제공하는 IsNullOrEmpty 메소드를 사용하기도 하겠지.

// C# code to simplify checking for null and empty string
if ( !string.IsNullOrEmpty(someString) ) {
    //Do something here...
}

하지만 자바스크립트에서는 그럴 필요가 없어. 코딩을 적절히 짧게 하는건 로직을 이해하기 더 쉽다는 뜻이겠지.

// Simplified JavaScript syntax to check for
// undefined, null, & empty string values
if ( someString ) {
    //Do something here...
}

덧붙이자면 위 코드의 someString 이라는 변수는 애메하게 붕뜬 상태이거나 정의되지 않았어도 이상없이 참과 거짓을 체크할 수 있다고.


- 기본값 세팅하는 법

시샵에서 기본 값을 세팅하는 법은 몇가지가 있지만 아래의 코드들을 가장 안전한 세팅으로 사용하자나

// C# example. Don't do this in JavaScript
if ( someString == null ) {
   someString = "default Value";
}
 
// Slightly better, but don't do this either
someString = someString ? someString : "default value";

하지만 자바스크립트에서는 아래처럼도 가능하다는 것이지. 무척 심플.

// JavaScript syntax to set a default value
someString = someString || "default value";



☞ 좋은 습관

참과 거짓을 판단하는 것부터 널 체크, 기본 값 대입에서 자바스크립트 개발자라면 변수 자신을 체크하는 습관을 들여보자고.



5. Using the Wrong Comparison Operators

비교연산자 (== , !=) 를 사용할 때 자바스트립트는 두 값을 같은 타입으로 강제하는 방법을 통해 비교를 하고 있어. 이건 편하긴 하지만 역시 약간 아리까리해. 아래 코드를 보고 어떤 결과가 나올지 예상해보자고.

// Unexpected Comparisons using the == Operator
0          ==  ''        //true
0          ==  '0'       //true
false      ==  '0'       //true
null       ==  undefined //true
' \t\r\n ' ==  0         //true


- 때로는 === 나 !== 를 사용해 보자!

===, !== 연산자는 좀 더 엄격히 값을 비교하는 연산자야. 식의 결과 값만 비교하는 것이 아니라 타입까지 비교하기 때문이야. 타입이 명확한 언어에서 비교하는 과정과 비슷하지. 위의 코드를 그대로 두고 연산자만 바꿔서 비교해보면 아래와 같은 결과가 나와.

// Expected Comparisons using the === Operator
0          === ''        //false
0          === '0'       //false
false      === '0'       //false
null       === undefined //false
' \t\r\n ' === 0         //false

뭐 당연한 결과.


☞ 좋은 습관

두 값을 비교할 때 에매한 에러를 피하려면 ===, !== 비교 연산자를 사용하셈.




6. Not Using the for…in Statement Correctly

시샵에서 코딩할 때 전통적인 C 스타일 대신 for…in 루프를 사용했었지. 자바스크립트에서는 상황마다 조금 다르기 때문 주의해야해.

- 배열에서 사용할 때

배열의 첨자로 루프를 돌릴 때 for…in 대신 for 를 사용해야해. for…in 은 사용하지 마.
for…in 문은 아이템의 순서를 고려하지 않기 때문이야. 대충 감이 오지? 흥미진진한 버그를 만날 수 있어.
아래 코드를 보자고. 5번째 요소를 "test" 라고 지정했을 경우 배열의 길이는 6 이야.

var myArray = [], name;
myArray[5] = "test";
console.log( myArray.length ); //6

만약에 for…in 문을 사용한다면 어떨까. 배열의 순환하는데 있어서 우리가 예상한 방법과 다른 방식으로 배열을 돌게되는 모습을 볼꺼야.
그리고 이 결과가 의도한대로 잘 나온거라면 배열 대신 일반 객체를 사용해야해.

var myArray = [], name;
myArray[5] = "test";
console.log( myArray.length ); //6
 
for ( name in myArray ) {
    console.log( name, myArray[name] );
    //Outputs...
    //   5, test
}

배열에 적합하게 for 반복문을 사용하려면 아래처럼 코딩해애햐. 각 배열 원소의 값이 없더라도 배열 전체를 순환하는 루프는 for 반복문이야.

var myArray = [], name;
myArray[5] = "test";
console.log( myArray.length ); //6
 
for ( var i = 0, length = myArray.length; i < length; i++ ) {
    console.log( i, myArray[i] );
    //Outputs...
    //   0, undefined
    //   1, undefined
    //   2, undefined
    //   3, undefined
    //   4, undefined
    //   5, test
}

로직에 확신이 없다면 배열에는 for…in 을 사용하지 않는게 좋겠지. 뭐 원하는 목적이 있어서 배열에 prototype 을 조작하는 등의 배열객체로 사용한다면 상관 없고.

var myArray = [], name;
myArray[5] = "test";
console.log( myArray.length ); //6
 
Array.prototype.someVariable = "Where did this come from?";
for ( name in myArray ) {
    console.log( name, myArray[name] );
    //Outputs...
    //   5, test
    //   someVariable, Where did this come from?
}

곧 이어서 일반객체에 for…in 을 사용하는 방법을 알아보자고.

- For…In 에서 객체를 사용할 때 주의할 점

위에서 배열에는 For…In 을 사용할 때 주의점을 확인했어. For…In 의 기본적인 사용법은 아래와 같아.

for ( var name in object ) {
    //Your code here
}


참 평범한 코드야. 그치? 게다가 대부분의 경우 제대로 작동하기도 하고. 조심해야할 상황을 알아보자고.

For…In 문은 기본적으로 객체의 모든 프로퍼티를 반복하는 프로세스를 가지고 있어. 모든 프로퍼티는 프로토타입으로 할당받은 것도 포함해서 말이지. 프로토타입으로 확장한 프로퍼티를 구분하여 루프를 돌고 싶을 경우에는 아래와 같은 프로세스를 거쳐야하겠지.

/* Check if object has property before
iterating, because functions inherited
from prototype are also included */
for ( var name in object ) {
   if ( object.hasOwnProperty(name) ) {
      //Your code here
   }
}


For…In 문을 사용하는 적절한 예제를 보자고.


var Person = function( firstName, lastName ) {
  this.firstName = firstName;
  this.lastName = lastName;
  return this;
};
 
Person.prototype = {
  isMarried : false,
  hasKids: false
};
 
var john = new Person( "John", "Smith" ),
  linda = new Person( "Linda", "Davis" ),
  name;
 
john.isMarried = true;
 
console.log( "Not Checking hasOwnProperty" );
for ( name in john ) {
  console.log( name + ": " + john[name] );
  //Outputs
  //  firstName: John
  //  lastName: Smith
  //  isMarried: true
  //  hasKids: false
}
 
console.log( "Checking hasOwnProperty" );
for ( name in linda ) {
  if ( linda.hasOwnProperty(name) ) {
    console.log( name + ": " + linda[name] );
    //Outputs
    //  firstName: Linda
    //  lastName: Davis
  }
}


위 코드는 Person 객체를 만들어 john, linda 라는 인스턴스를 생성했어. 그리고 prototype 을 확장하여 두개의 프로퍼티를 추가했어.

그냥 단순히 For…In 를 돌면 확장한 객체의 프로퍼티도 출력이 되고 있어.

.hasOwnProperty() 를 통해 본연의 프로퍼티만 출력해주는 코드도 확인해봐.



☞ 좋은 습관

배열을 루핑할 때에는 for 를 사용 할 것.
For…In 을 사용할 때에는 hasOwnProperty 메소드를 고려하여 코딩할 것.




Conclusion

자바스크립트 라이브러리 jQuery 짱 -ㅅ-;