2012-02-14 1 views
5

누군가 나에게 설명 할 수 있을까요?Javascript에서 완전히 생성되기 전에 변수를 사용하고있는 것처럼 보입니다. 그러나 이것이 작동합니다 - 이유는 무엇입니까?

var diagramImage = new Kinetic.Shape(function() { 
    var context = this.getContext(); 
    context.beginPath(); 
    context.lineWidth = 1; 
    //This is crazy tricks. It's part of the KineticJS demo website, but how am I able to assign diagramImage.color here? 
    context.strokeStyle = diagramImage.color; 

    var lastVertice = polygon.Vertices[polygon.Vertices.length - 1]; 

    context.moveTo(lastVertice.X, lastVertice.Y); 

    for (var i = 0; i < polygon.Vertices.length; i++) { 
     var vertice = polygon.Vertices[i]; 
     context.lineTo(vertice.X, vertice.Y); 
    } 

    context.stroke(); 
    context.closePath(); 
}); 

diagramImage이 운동 생성자 돌아갈 때까지 존재하지 않는 날 것으로 보인다,하지만 난 수 있어요 (그리고해야 할 것 같다) 문맥의 strokeStylediagramImage에 색상 지정 - diagramImage가 생성되기 전에? 왜이게 효과가 있니?

편집 : 전체 코드 :

function DrawPolygon(diagramLayer, polygon) { 
    var diagramImage = new Kinetic.Shape(function() { 
     var context = this.getContext(); 
     context.beginPath(); 
     context.lineWidth = 2; 
     //This is crazy tricks. It's part of the KineticJS demo website, but how am I able to assign diagramImage.color here? 
     context.strokeStyle = diagramImage.color; 

     var lastVertice = polygon.Vertices[polygon.Vertices.length - 1]; 

     context.moveTo(lastVertice.X, lastVertice.Y); 

     for (var i = 0; i < polygon.Vertices.length; i++) { 
      var vertice = polygon.Vertices[i]; 
      context.lineTo(vertice.X, vertice.Y); 
     } 

     context.stroke(); 
     context.closePath(); 
    }); 

    diagramImage.color = "red"; 

    diagramImage.on("mouseover", function() { 
     this.color = "green"; 
     diagramLayer.draw(); 
    }); 

    diagramImage.on("mouseout", function() { 
     this.color = "red"; 
     diagramLayer.draw(); 
    }); 

    diagramLayer.add(diagramImage); 
    planViewStage.add(diagramLayer); 
} 
+0

포함 된 코드 부분 앞에'diagramImage'가 이미 정의되어 있습니까? – ziesemer

+0

아니요.이 자습서를 참조하십시오. http://www.html5canvastutorials.com/labs/html5-canvas-interactive-flower/ 변수 'center'를 사용하여 동일한 작업을 수행합니다. –

+0

게시 할 수있는 추가 코드가 있습니까? 당신의 주장? – shanabus

답변

8

Kinetic.Shape 생성자에 전달되는 폐쇄/함수 내에서 어디에 있는지 diagramImage.color를 호출하기 때문에. 이 함수는 생성자에 의해 생성 된 새 인스턴스가 diagramImage에 할당 될 때까지 생성자에 의해 호출되지 않거나 실행되지 않습니다.

var MyObject = function(f){ 
    this.myFunc = f; // f is executed sometime later... 
}; 
MyObject.prototype.execute = function(){ 
    this.myFunc(); 
}; 

var myObjInst = new MyObject(function(){ 
    console.log("myObjInst:", myObjInst); 
}); 
myObjInst.execute(); 

Twisol가 언급 한 바와 같이,이 대신 this를 사용하여 개선 될 수있다 :

여기에 더 나은 무슨 일이 일어나고 있는지 설명 할 수있는 최소한의 예입니다. 예를 들어 : API에서 문서화하지 않는

(function(){ 
    var MyObject = function(f){ 
    this.myFunc = f; // f is executed sometime later... 
    }; 
    MyObject.prototype.execute = function(){ 
    this.myFunc(); 
    }; 

    var myObjInst = new MyObject(function(){ 
    console.log("myObjInst:", this); 
    }); 
    myObjInst.execute(); 
})(); 

그러나, 크리스가 언급 한 바와 같이, - this 콜백하는 동안 Kinetic.Shape를 참조 것이라는 보장이 없다 - 그래서 여전히 이러한 2의 더 나은 여기 diagramImage를 계속 사용 옵션. 간단히 말해서, 이것이 최고의 API/예제/자바 스크립트 사용이 아니라고 생각합니다.이 자바 스크립트를 다루어야 만하는 뉘앙스라고 생각하지 않을 것입니다. 물론, 당신이 필요하다면 이러한 뉘앙스가 있습니다. 그러나 당신은 그렇게 할 필요가 없습니다.

+0

이 코드를 더 만들 수있는 방법이 있습니까? 직관적입니까? 아니면 내가 사랑하는 법을 배워야 할 Javascript의 뉘앙스인가? :) –

+0

소스 (문자 그대로) [여기] (http://www.kineticjs.com/download/kinetic-v3.7.3.js). 'drawFunc'는'Kinetic.Shape'도 아니고'Kinetic.Node'도 아니지만'drawFunc'라고 불리우는 속성으로 말합니다. – Twisol

+1

@SeanAnderson : 예,'diagramImage' 대신 함수에서'this'를 사용하십시오. 이것은'drawFunc' *가 호출 될 때 올바른 객체를'this'로 제공하기 때문에 여기서 할 수 있습니다. – Twisol

0

는이 게시물이 그것을 설명 할 수 있습니다 생각 - 연관 배열에 http://www.quirksmode.org/js/associative.html

특히 섹션. 이 글은 자바 스크립트의 객체도 연관 배열로 간주한다고 설명합니다.

따라서 diagramImage.strokeStyle이 명시 적으로 정의되지는 않지만 여전히 diagramImage['strokeStyle']을 참조 할 수 있습니다.

도움이 되었습니까?

1

흥미로운 구성입니다. 무슨 일이 일어나고있는 것으로 보입니까 :

  • diagramImage은 선언으로 인해 할당되기 전에 참조입니다. 이를 시각화하려면 var diagramImage이 그 자체로 이전 행에 있었다고 상상해보십시오.
  • Kinetic.Shape은 익명 함수를 나중에 사용할 생성자 인수 중 하나로 콜백합니다.
  • 콜백은 Kinetic.Shape 개체를 참조하려고합니다. 아마도 this이 나중에 참조하는 내용 (this.getContext() 사용에 의해 표시됨)을 설명하는 일부 계약이 있으며 Kinetic.Shape 개체가 아닙니다.
  • diagramImage은 참조이며 참조 번호가 사용될 때까지 새로운 Kinetic.Shape이 할당 될 것입니다. 말한 목적으로 사용하는 것이 정성을 다할 것입니다.

원칙적으로 지역 변수를 사용하여 콜백에서 현재를 사용할 수 있도록하는 일반적인 패턴과 다르지 않습니다. 그것은 그냥 여기에 변수가 나중에 사용할 수있게되는 것

var self = this; 
$('myelement').click(function(){ self.hi = true; }); 

는 상기 물체의 멤버의 현재 개체가 아닙니다.

+0

http://en.wikipedia.org/wiki/Closure_(computer_science) –

관련 문제