2014-12-02 2 views
2

내가 Scala.js이 자바 스크립트 함수를 포팅하고 있습니다 : 여기 arguments.callee를

once: function (el, type, callback) { 
    var typeArray = type.split(' '); 
    for (var i = typeArray.length - 1; i >= 0; i--) { 
    el.addEventListener(typeArray[i], function(e) { 
     e.target.removeEventListener(e.type, arguments.callee); 
     return callback(e); 
    }); 
    }; 
}, 

는 스칼라 코드 작성에서 내 시도 :

def once(element: TopNode, tpe: String, callback: Function1[Event,Any]): Unit = { 
    tpe.split(" ").foreach(item => element.addEventListener(item, (e : Event) => { 
    e.target.removeEventListener(e.`type`, ?) // <-- what do I put here? 
    callback(e) 
    })) 
} 

가 어떻게 참조 할 수 있습니다 내 그 장소 소유자의 람다?

답변

4

Scala.js에는 arguments.callee에 해당하는 JavaScript가 없습니다. 더 일반적으로는 arguments과 같지 않습니다. 그래서 람다는 그것이 포착 된 환경을 통해 주어지지 않는 한 자체에 대한 참조를 읽을 수 없습니다. 이는 방법의 val에 람다를 저장하여 얻을 수 있습니다. 이상적으로, 하나는이를 작성하려합니다 : 당신이 그 정의의 오른쪽에 (여기 cb)는 발을 사용할 수 없기 때문에 그러나

def once(element: TopNode, tpe: String, 
    callback: Function1[Event,Any]): Unit = { 
    val cb: js.Function1[Event, Any] = { (e: Event) => 
    e.target.removeEventListener(e.`type`, cb) // using cb here 
    callback(e) 
    } 
    tpe.split(" ").foreach(item => element.addEventListener(item, cb)) 
} 

이 그에게 일어나는 경우에도, 컴파일되지 않습니다 람다 안에있어. 일을하려고하는 것은 그래서 다음과 같은 컴파일 오류가 발생합니다 :

Main.scala:17: error: forward reference extends over definition of value cb 
     e.target.removeEventListener(e.`type`, cb) // using cb here 

간단한 솔루션은, 비록 있습니다 : 사용하십시오 lazy val 대신 :

def once(element: TopNode, tpe: String, 
    callback: Function1[Event,Any]): Unit = { 
    lazy val cb: js.Function1[Event, Any] = { (e: Event) => 
    e.target.removeEventListener(e.`type`, cb) // using cb here 
    callback(e) 
    } 
    tpe.split(" ").foreach(item => element.addEventListener(item, cb)) 
} 

js.Function1 아닌 Function1cb를 선언해야합니다 . 그렇지 않으면 cb 자체가 스칼라 함수를 참조하지만 자동 변환으로 인해 생성 된 JS 함수 (다른 ID가 있음)는 참조하지 않습니다. cb이 JS 기능을 참조하는지 확인해야합니다.

피들 : http://www.scala-js-fiddle.com/gist/2b848e2f01e7af522dc1