자바스크립트 호이스팅(hoisting)이란?



자바스크립트에서는 var 선언문 전에 변수를 사용해도 이미 선언된 것으로 간주한다.


이런 동작 방식을 "호이스팅"(hoisting)이라고 한다.

  1. alert(typeof fn1); // undefined
  2. alert(typeof value1); // undefined
  3.  
  4. var fn1 = function(){ ; };
  5. var value1 = 'value1';
  6.  
  7. alert(typeof fn1); // function
  8. alert(typeof value1); // string

1. 자바스크립트는 실행시 모든 변수가 선언 됩니다. 즉, 결과 에서 처럼 변수를 정의 하기전
결과는 모두 "undefined"를 반환 합니다.


2. 하지만 정의된 후의 결과는 각각 function 과 string을 반환 합니다.

  1. alert(typeof fn1); // function
  2.  
  3. function fn1(){ ; };
  4.  
  5. alert(typeof fn1); // function

1. 하지만 위와 같이 함수 리터널 방식이 아닌 함수 선언문 방식으로 작성한 전역 fn1()
함수 객체는 v
ar선언문 이전의 결과 에서도 function() 을 반환 합니다.


즉, 함수 선언문으로 선언된 변수는 호이스팅 동작에서 정의된 값이 위로 끌어 올려집니다.


아래 코드와 같이 함수 스코프 안에서도 전역과 똑같은 방식으로 호이스팅이 동작합니다.

  1. function fn(){
  2.    
  3.     alert(typeof name); // undefined
  4.     alert(typeof inner_fn); // function
  5.  
  6.     var name = 'name';
  7.  
  8.     function inner_fn(){
  9.     }
  10.  
  11.     alert(typeof name); // string
  12.     alert(typeof inner_fn); // function
  13. }
  14.  
  15. fn();

자바스크립트 call by value or call by reference


모든 OOP 언어에서다루고 있는 부분 이라고 할 수 있는 값(value)참조값(ref value)에 대해 "자바스크립" 에서는
어떻게 다루고 있는지 알아 보도록 하겠습니다.


 var value = '';
    var ref = {};
    
    function callbyvalueReference(value, ref) {

        value += 'value';
        ref.name = 'reference';
    }


    callbyvalueReference(value, ref);

    alert(value); // value
    alert(ref.name); // reference


1. value 변수와 ref 변수에 각 각 "값" 과 "객체"를 선언 및 정의 합니다.
 

2. 이렇게 정의된 2개의 변수를  fn(value, ref);  호출 합니다.

3. 값의 복사본인 함수 매개변수 value는 해당 함수의 지역 변수로 선언되고 정의 됩니다.
 

"즉, 전역변수로 선언 및 정의된 value의 문자열과는 "+=" 연산자를 통해 합쳐 지지 않는
다는 것을 말합니다."


4. 하지만 객체를 정의한 ref 전역 변수는 함수의 매개변수로 "값" 과 "복사복" 이 아닌 값에 의한 참조지역변수로
전달 되었기 때문에 내부에서 언제든 참조값 수정이 가능하게 되었습니다.



P.S 문자열 복사와 전달

위의 설명에서 자바스크립트에서 객체는 참조만 전달된다고 하였습니다.

그렇다면 문자열은 기본타입인 값(call by value)에 의한 참조이며, 매개변수 전달 시 값에 복사본이 전달된다는 말이 됩니다.

그러나 문자열의 길이는 임의적이기때문에 문자열을 바이트 단위로 복사하거나 전달, 비교하는 일은 매우 비효율적인 이기때문에 문자열은 참조 타입 형태로 구현되었다고 가정하는 것이 더 적절합니다.

위의 내용처럼 문자열이 값에 대한 참조인지 알 수 있는 방법은 없으나, 문자열 비교를 통해 값에 의해 비교되는지 참조로 비교되는지 알 수는 있습니다.

  1. // 만약 두 문자열이 값에 의해 비교되면 두 문자열은 동일할 것이고 참조에 의해 비교되면 동일하지 않을 것이다.
  2.  
  3. var s1 = 'hello';
  4. var s2 = 'hell' + 'o';
  5.  
  6. alert(s1 === s2); //true
  7.  
  8. var obj1 = {
  9.     str: 'hello'
  10. }
  11.  
  12. var obj2 = {
  13.     str: 'hell' + 'o'
  14. }
  15.  
  16. alert(obj1.str === obj2.str); //true


아래는 간단한 객체 상속 관계에서 참조값을 다루는 코드예제 입니다.

  1. function fn(){
  2. }
  3.  
  4. fn.prototype = {'arr': []};
  5.  
  6. new fn().arr.push(1);
  7.  
  8. alert(new fn().arr); // 1


1. fn() 함수 객체가 생성 됩니다.

2. fn() 함수 객체의 프로토타입 맴버에 객체({'arr': []})를 추가 합니다.

3. fn() 객체의 프로토타입 맴버에 추가된 객체의 arr 배열 속성에 1을
push() 함수로 1을 추가 합니다. 


4 . 
alert(new fn().arr); // 1  에서 "1" 이 반환되는 이유는? 

"자바스크립트" 에서 객체는 참조만 전달되기 때문이다. 즉, 자식( new fn() ) 객체 에서 속성 ({'arr': []})  값을 수정하면 부모 객체 속성 ({'arr': []}또한 수정되어 버립니다.

 


자바스크립트 prototype chain


1. 프로토타입이란?


자바스크립트에서 모든 객체는 prototype에 기반합니다.
 

프로토타입은 다른 객체의 기반이 되는 객체이고, 새 객체가 가져야 할 맴버를 정의하고
구현 합니다.


객체는 내부 속성을 통해 자신의 프로토타입에 묶입니다. IE를 제외한 표준 브라우져들에서는
__proto__라는 이름으로 노출하여, 개발자가 사용할 수 있지만, [[Scope]]속성과
마찬가지로 코드에서 접근할수 없습니다.




또한 객체의 맴버는 인스턴스 맴버와, 프로토타입 맴버 두가지입니다.

인스턴스 맴버객체 인스턴스 자체에 있고, 프로토타입 맴버는 객체의 프로토타입에
있습니다.


1. A 생성자 함수의 Prototype Chain 도식화 예제 입니다.




1. A 생성자 함수는 Function()입니다.


2. A 함수 객체의 Constructor는 Function() 이며, 즉 Function.prototype 맴버를 상속 받고 Function.prototype 객체 속성은 Object.prototype 맴버를 상속 받습니다. 

3. A
.prototype 객체 속성은 Object.prototype 맴버를 상속 받습니다.








2. new A 객체가 추가된 Prototype Chain 도식화 예제 입니다.




1. A 생성자 함수는 Function()입니다.

2. A 함수 객체의 Constructor는 Function() 이며, 즉 Function.prototype 맴버를 상속 받고 Function.prototype 객체 속성은 Object.prototype 맴버를 상속 받습니다. 

3. A
.prototype 객체 속성은 Object.prototype 맴버를 상속 받습니다.
 

4. New A객체의 __proto__ 속성은 A.prototype과 연결됩니다.



아래는 지금 까지의 설명에 대한 예제코드 입니다.


  1. function A(){
  2.     this.name = 'name';
  3. }
  4.      
  5.      
  6. A.prototype.getName = function(){
  7.     return this.name;
  8. }
  9.  
  10.  
  11. alert(A.constructor); // Function()
  12. alert(A.prototype.constructor); // A()
  13. alert(A.prototype.hasOwnProperty); // Object.hasOwnProperty()
  14. alert(Function.prototype.hasOwnProperty); // Object.hasOwnProperty()
  15.      
  16. alert(new A().name); // name
  17. alert(new A().getName()); // name
   
prev 1 ··· 49 50 51 52 53 54 55 56 next