자바스크립트의 독특한 특징

김민재·2023년 4월 12일
0

목록 보기
6/7
  • 구문과 동작 방식에 있어 자바스크립트 만이 지니는 예외적 사례와 특징

  • 자바스크립트는 동적 인터프리터 프로그래밍 언어이므로 다른 전통적 객체지향 프로그래밍 언어들과 구문이 다름

  • 시간 및 알고리즘 공간 복잡도 분석을 위한 빅오 표기법 개념

  • 시간(실행시간)과 공간(사용된 메모리) 관점에서 알고리즘 구현을 분석하는 법 이해


1. 자바스크립트 범위

  • 범위(scope)는 자바스크립트 변수에 대한 접근 권한을 정의
  • 자바스크립트에서 변수는 전역범위 또는 지역 범위에 속함
  • 전역 변수는 전역 범위에 속하는 변수로 어디에서나 해당 변수에 접근 가능

1_1 전역 선언 : 전역 범위

  • 자바스크립트에서 연산자 없이 변수를 선언 가능
test = "sss";
console.log(test); // prints "sss"
  • 위와 코드는 전역 변수를 생성하지만 위 선언 방식은 가장 안좋은 사용법 중 하나
  • var, let을 사용해 변수를 선언, 수정하지 않는 변수 선언 시 const로 선언

1_2 var를 사용해 선언: 함수 범위

  • var는 변수 선언하는데 사용되는 키워드로 어디에서 선언하든 변수 선언이 함수의 맨 앞으로 이동하는데 이를 호이스팅이라도 함
  • 스크립트 실행 시 변수가 스크립트 가장 마지막에 선언되어도 선언 코드가 가장 마지막에 실행되는 게 아님
function scope1(){
    var top = "top";
    bottom = "bottom";
    console.log(bottom);
    var bottom;
}
scope1(); // prints "bottom" - no error
// 실제 동작하는 방식
function scope1(){
    var top = "top";
    var bottom;
    bottom = "bottom";
    console.log(bottom);
}
scope1(); // prints "bottom" - no error
  • scope1() 함수 가장 마지막 줄 위치한 bottom 변수 선언이 맨 앞으로 이동해 변수 출력은 오류 없이 수행
  • 즉 var 키워드는 변수 범위가 가장 가까운 함수 범위라는 것을 의미한다
function scope2(print) {
    if (print) {
        var insideIf = '12';
    }
    console.log(insideIf);
}
scope2(true); // prints '12' - no error
// 실제 동작하는 방식
function scope2(print) {
    var insideIf;
    if (print) {
        insideIf = '12';
    }
    console.log(insideIf);
}
scope2(true); // prints '12' - no error
  • scope2 함수는 insideIf 변수와 가장 가까운 함수 범위
  • 자바에선 위 구문은 오류를 일으키는데 insideIf 변수가 if문 블록 내에서만 사용 가능하고 if문 블록 외부에선 사용할 수 없기 때문
var a = 1
function four() {
    if (true) {
        var a = 4;
    }
    console.log(a); // prints '4'
}
four();
  • 전역변수 값인 1이 아닌 4가 출력되는 건 a 변수가 four 함수 내 재선언되어 사용 가능하기 때문

1_3 let을 사용해 선언: 블록 범위

  • 변수 선언 시 let을 사용 해 선언하면 선언된 변수는 가장 가까운 블록 범위를 갖는다 (즉, 변수가 선언 된 {}내에서 유효)
function scope3(print) {
    if (print) {
        let insideIf = '12';
    }
    console.log(insideIf);
}
scope3(true); // prints ''
  • 콘솔에 아무것도 출력되지 않는 이유는 insideIf 변수가 if문 블록 내에서만 사용 가능하기에

--

2. 등가와 형

  • 자바스크립트엔 자바와 같은 전통적인 언어와 다른 자료형이 있는데 이런 점이 등가 비교와 같은 것들에 어떤식으로 영향을 미치는지 알아보자

2_1. 변수형

  • 자바스크립트엔 boolean, number, string, undefined, object, function, symbol과 같은 7개의 기본 자료형 존재
  • 특이한 점은 선언만 되고 값이 할당되지 않은 변수엔 undefined가 할당 된다는
var is20 = false; // boolean
typeof is20; // boolean
var age = 19;
typeof age; // number
var lastName = "Bae";
typeof lastName; // string
var fruits = ["Apple", "Banana", "Kiwi"];
typeof fruits; // object
var me = {firstName:"Sammie", lastName:"Bae"};
typeof me; // object
var nullVar = null;
typeof nullVar; // object
var function1 = function(){
	console.log(1);
}
typeof function1 // function
var blank;
typeof blank; // undefined

2_2. 참/거짓 확인

  • if문 내에 참/거짓 확인 사용되는데 많은 언어의 경우 if()함수 내 매개변수는 boolean 형이어야하지만 자바스크립트는 더 유연하다
if (node) {
}
  • node는 변수로 변수가 비거나 null 또는 undefined면 해당 변수는 false로 평가
  • 다음은 false로 평가되는 경우
    • false
    • 0
    • 빈 문자열
    • NaN
    • undefined
    • null
  • 다음은 true로 평가되는 경우
    • true
    • 0이 아닌 다른 숫자
    • 비어있지 않은 문자열
    • 비어있지 않은 객체
var printIfTrue = '';
if (printIfTrue) {
    console.log('truthy');
} else {
    console.log('falsey'); // prints 'falsey'
}

2_3. ===대 ==

  • 자바스크립트는 스크립트 언어로 변수 선언 시 변수에 형이 할당되지 않고 대신 코드가 실행 될 때 해당 변수의 형이 해석
  • 따라서 ===는 ==보다 등가(양쪽이 같은지 여부)를 더 엄격히 확인
  • ==가 값만 확인하는 반면 ===는 형과 값 모두 확인
"5" == 5 // returns true
"5" === 5 // returns false
  • "5" == 5 는 true를 반환하는데 "5"가 비교 전 숫자로 강제 변환 되기 때문이고 반면 "5" == 5는 문자열과 숫자 타입까지 비교해 false를 반환

2_4. 객체

  • 자바와 같은 강 자료형 언어는 isEquals()를 사용해 두 객체가 동일한지 확인하나 자바스크립트에선 두 객체가 동일한지 확인하고자 == 연산자를 써도 true로 평가되지 않는다
var o1 = {};
var o2 = {};
o1 == o2 // returns false
o1 === o2 // returns false
  • 위 객체는 동일(동일한 속성과 값을 지님)함에도 두 객체는 동일하지 않은데 두 변수의 메모리상 주소가 다르기 때문
  • 이것이 자바스크립트 애플리케이션 lodash나 underscore와 같은 유틸리티 라이브러리를 사용하는 이유로 두 라이브러리엔 두 객체 혹은 두 값을 정확히 확인할 수 있는 isEqual 함수가 존재
  • isEqual 함수가 속성 기반 등가 비교 방식으로 구현되어 객체의 각 속성을 비교
function isEquivalent(a, b) {
    // arrays of property names
    var aProps = Object.getOwnPropertyNames(a);
    var bProps = Object.getOwnPropertyNames(b);
    // If their property lengths are different, they're different objects 
    if (aProps.length != bProps.length) {
        return false;
    }
    for (var i = 0; i < aProps.length; i++) {
        var propName = aProps[i];
        // If the values of the property are different, not equal
        if (a[propName] !== b[propName]) {
            return false;
        }
    }
    // If everything matched, correct
    return true;
}
isEquivalent({'hi':12},{'hi':12}); // returns true
  • isEquivalent 함수는 문자열이나 숫자 하나만을 속성으로 갖는 객체에 대해서 도 잘 동작
var obj1 = {'prop1': 'test','prop2': function (){} };
var obj2 = {'prop1': 'test','prop2': function (){} };
isEquivalent(obj1,obj2); // returns false
  • 위 처럼 isEquivalent 함수가 잘 동작하는 이유는 함수와 배열이 등가 비교를 위해 단순히 == 연산자를 사용하는 것이 아니기 때문
var function1 = function(){console.log(2)};
var function2 = function(){console.log(2)};
console.log(function1 == function2); // prints 'false'
  • 두 함수가 동일한 연산을 수행하지만 두 함수의 메모리상 주소는 다르기에 등가 연산자는 false를 반환
  • 기본 등가 확인 연산자인 ==와 ===는 문자열과 숫자에만 사용 가능하며 객체에 대한 등가 확인을 구현 하려면 객체의 각 속성 확인해야함

요약

  • 자바스크립트엔 대부분 프로그래밍 언어들이 사용하지 않는 다른 방식의 변수 선언 방식 존재
    - var는 함수 범위 내 변수 선언
    • let은 블록 범위에서 변수 선언하고 아무 연산자 없이 변수 선언하면 해당 변수는 전역 범위에서 선언 됌(전역 범위로 변수 선언하는 것은 피해야함)
  • 형 확인 위해 typeof를 사용해 원하는 형이 맞는지 검증 가능
  • 등가 확인 위해 값에 대해선 == 사용 값과 형 모두 같은지 확인하기 위해 === 사용하나 ==와 ===는 숫자, 문자열, 불리언 같은 비객체형만 사용 가능
profile
자기 신뢰의 힘을 믿고 실천하는 개발자가 되고자합니다.

0개의 댓글