S55 – 1st

기완형님이 하시는 S55 스터디를 다녀왔습니다. 열정적인 강의에 폭풍 감동 ㅠㅠ 하지만 내용에는 멘붕~ @,.@ 스터디를 들으며 생긴 몇 가지 궁굼한 점들이 있어서 남겨 봅니다. 물론 물어 볼 수도 있지만 직접 찾아보지 않으면 기억에 남지 않으니 나름대로 공부해 봤습니다. 저 같은 자바스크립트 입문자 분들에게 도움이 되지 않을 가 싶습니다.

질문1) [[Prototype]] 과 prototype 은 같은 것인가?

자바스크립트 객체는 기본적으로 해시맵 구조이므로 아무런 키를 넣어서 만들 수 있습니다. 다만 생성시 기본 할당되는 키가 있는 데 [[Prototype]] 과 같은 것들입니다. 저는 단순히 설명 만 듣고 오브젝트에 키 값으로 [[Prototype]] 가 정말 있는 줄 알았습니다.  [[Prototype]]는 사용자가 직접 접근 할 수 있는 키가 아닌 처리기가 해석시 사용하는  키입니다. 즉, var obj = {}; obj.[[Prototype]]; 처럼 사용 할 수 는 없습니다.

prototype 속성으로 접근 할 수 있느나 아무곳에서 쓸 수 있는 것은 아닙니다. 아래 코드와 같이 함수객체에만 사용 할 수 있습니다.

var obj = {};
obj.prototype; // undefined
var fn = function(){};
fn.prototype; // Object {}
var iFn = new fn();
iFn.prototype // undefined

질문2) var foo; foo를 지우고 싶다 어떻해야 하나?

결론부터 말하면 삭제 할 수 없습니다.

bar = 1; //1
delete bar; //true
var foo = 1; //undefined
delete foo; //false

var 키워드는 해당 함수의 스코프 영역에 변수를 등록합니다. 그래서 저는 [[Scope]] 에 접근 할 수 있으면 해당 변수도 delete 할 수 있을거라 생각 했는데 (그렇게 배운 것 같은데;;) 우선 [[Scope]] 에 접근할 수 없으며 변수 또한 delete 할 수 없습니다.

참고 : http://perfectionkills.com/understanding-delete/

어디에 써 먹을 것인가?

힘들게 공부 했으니 써먹을 궁리를 해야겠지요. 제 경우는 아무래도 어플리케이션 보다는 그래픽 쪽이므로 뭔가 그래픽적으로 멋진 결과물을 만드는 것에 포커스 하고 있습니다. 먼저 어제 배운내용을 Unity3D 에 적용해봤습니다.

Unity3D

#pragma strict

function Start()  {
	Debug.Log(this); //Cube (First)
	Debug.Log(rotate); // CompilerGenerated.__First_Start$callable0$5_19__
}

function Update()  {
	rotate(1, 0, 0);
}

function rotate(x, y, z) {
	this.transform.Rotate( Vector3(x, y, z) );
}

먼저 유니티에서도 호이스팅은 잘 작동합니다. 하지만 아래와 같은 코드는 에러가 납니다.

function Update()  {
	rotate(1, 0, 0);
	
	function rotate(x, y, z) {
		this.transform.Rotate( Vector3(x, y, z) );
	}
}

함수 안에서 함수를 생성 할 수 없으며 심지어 프로토타입도 없습니다.@..@ 아무래도 모양만 자바스크립이지 컴파일러가 전혀 달라서 작동하는 방식 또한 다른 것 같습니다. (이러면 곤란한데…)

Canvas

function Start()
{
    canvas = document.getElementById('cube');
    canvasWidth = canvas.width;
    canvasHeight = canvas.height;

    if (canvas.getContext){
      context = canvas.getContext('2d');
      timer = setInterval(Update, 1000 / 60);
    }
}

function Update()
{
    rotate(1);
}

function rotate(r){
    context.clearRect(0, 0, canvasWidth, canvasHeight);
    context.translate(canvasWidth/2, canvasHeight/2);
    context.rotate(Math.PI / 180 * r);
    context.translate(-canvasWidth/2, -canvasHeight/2);
    context.fillStyle = "blue";
    context.fillRect(canvasWidth/2 - 50, canvasHeight/2 - 50, 100, 100);
}

Start();

동일한 코드를 Canvas 를 이용해서 구현해보았습니다. 소스를 만들면서 다시 멘붕에 빠집니다. Start 함수에서 지정한 canvas, context 등의 변수는 분명 함수 안에서 선언된 지역변수 입니다. 그런데 어떻게 rotate 함수 안에서 참조가 되는 것 일까요? 참고로 어느정도 예상하시겠지만 var 로 변수를 선언하면 rotate 에서 참조 되지 않습니다.

흠 그래서 고민하다 똑똑한 저는 어제 배운 EC 가 생각 났습니다. Start 함수가 실행되고 있고 그 안에서 rotate 가 실행되니 EC 체인을 따라서 참조 하는 건가??? 물론 아닙니다. 그래서 또 어디서 줏어 들은 크롬의 V8 엔진이 생각 납니다. 그래! V8 은 모든 변수 참조를 미리 만든다고 했지 그럼 ie 에서 테스트 해보자! 그러나 ie8 에서는 Canvas 가 안됩니다;;;;;

결국 미궁으로 빠져 버렸습니다.

결론

확실한건 자바스크립트는 처리기에 따라서 다르게 작동한다는 것 입니다. 그리고 아무래도 제가 무서운 놈과 마주 했다는 사실 입니다. ㅎㅎㅎ

참고 : 지돌스타님의 http://blog.jidolstar.com/category/JavaScript 글들을 함께 보니 더욱 좋네요.

Comments (0)

    • 네 var 로 선언하지 않는 모든 변수는 global 에 잡히는 것이였군요. 그렇다는 것은

      function f1(){
          a = 1;
      }
      function f2(){
          console.log(++a);
      }
      

      위의 코드는 결국 아래와 같이 볼 수 있겠네요.

      function f1(){
          window.a = 1;
      }
      function f2(){
          window.console.log(++window.a);
      }
      

Leave a Comment

다음의 HTML 태그와 속성을 사용할 수 있습니다: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>