gpt4 book ai didi

javascript - scalajs 作用域中的对象和 js.global 作用域中的“相同”对象有什么区别?

转载 作者:行者123 更新时间:2023-11-28 19:38:47 25 4
gpt4 key购买 nike

我正在尝试编写一个简单的示例来使用 THREEJS 库渲染立方体。

package three

import org.scalajs.dom

import scala.scalajs.js
import scala.scalajs.js.Dynamic._
import scala.scalajs.js.annotation.JSName

object THREE extends js.Object
{
@JSName ("THREE.Scene")
class Scene extends js.Object
{
def add(obj: js.Object) = ???
}

@JSName ("THREE.Vector3")
class Vector3(var x:js.Number, var y:js.Number, var z:js.Number) extends js.Object

@JSName ("THREE.PerspectiveCamera")
class PerspectiveCamera(a:js.Number,b:js.Number,c:js.Number,d:js.Number) extends js.Object
{
var position:Vector3 = _
}

@JSName ("THREE.WebGLRenderer")
class WebGLRenderer(params:js.Dynamic) extends js.Object
{
def render(scene:js.Object, camera:js.Object) = ???
}

@JSName ("THREE.WebGLRenderer")
class SimpleWebGLRenderer() extends js.Object
{
def render(scene:js.Object, camera:js.Object) = ???
var domElement : js.Dynamic = _
}

@JSName ("THREE.BoxGeometry")
class BoxGeometry(a:js.Number,b:js.Number,c:js.Number) extends js.Object

@JSName ("THREE.MeshBasicMaterial")
class MeshBasicMaterial(params:js.Dynamic) extends js.Object

@JSName ("THREE.MeshBasicMaterial")
class SimpleMeshBasicMaterial() extends js.Object

@JSName ("THREE.Mesh")
class Mesh(geometry:js.Object, material:js.Object) extends js.Object

}


object ThreeExample
{
def render() =
{
val scene = new THREE.Scene()
val camera = new THREE.PerspectiveCamera(75, 1, 0.1, 1000);
val renderer = new THREE.WebGLRenderer(js.Dynamic.literal(
canvas = global.document.getElementById("ThreeCanvas")
));
val geometry = new THREE.BoxGeometry(1,1,1);
val material = new THREE.SimpleMeshBasicMaterial()
camera.position.z = 2;
val cube = new THREE.Mesh(geometry, material);

现在是有趣的部分。如果我尝试写

scene.add(cube);
renderer.render(scene, camera);

我明白了

<强>ScalaJS.c.jl_ClassCastException {s$1:“[object Object] 不是 scala.runtime.Nothing$ 的实例”,e$1:null,stackTrace$1:null,stackdata:TypeError,构造函数:function…}

错误。如果我尝试的话

global._scene = scene
global._cube = cube
global._camera = camera
global._renderer = renderer

global._scene.add(global._cube)
global._renderer.render(global._scene, global._camera);

一切都正确呈现,没有错误。我的意思是,有什么问题吗?global._scene 和 scene 或者 global._scene.add 和 scene.add 之间有区别吗?

最佳答案

详细说明我的评论:基本上没有区别。静态类型接口(interface)只是与动态类型接口(interface)所使用的相同机制的类型外观。但是,由于它是静态的,因此它会添加对您调用的方法返回的值的检查。

在您的情况下,当调用 renderer.render() 时,编译器会添加一个检查,以确保此 JavaScript 方法返回的值实际上符合 WebGLRenderer.render( )。但这个结果类型是什么?这是什么都没有!这是为什么?由于该方法的主体是 ???,其类型为 Nothing,因此 scalac 推断该方法的结果类型为 Nothing。然后检查失败,因为从 JavaScript 中 render 返回的值不是 Nothing 类型(显然,因为没有值具有该类型),这会导致 ClassCastException .

你想要的显然不是Nothing,而是Unit。因此,您所要做的就是使用 : Unit 明确显示此结果类型,如下所示:

def render(scene:js.Object, camera:js.Object): Unit = ???

一般来说,您应该始终在外观类型中显式指定方法的结果类型,因为否则它们会被推断为Nothing,这不是您想要的。

关于javascript - scalajs 作用域中的对象和 js.global 作用域中的“相同”对象有什么区别?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25453950/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com