为什么我的变量在 array.forEach 的嵌套函数中使用 undefined in Javascript

why is my variable in a nested function with array.forEach use undefined in Javascript

如果这里的答案很明显,我很抱歉,我主要是 c/c++ 人,javascript 对我来说比较陌生。

我正在使用三个,与 browserify 捆绑在一起。在一个模块中,我正在创建一个网格 object 数组,我需要使用 forEach(...) 在嵌套函数中访问它,但我不断收到错误,相应的 object 是没有定义的。我怀疑这个问题与我实际上在一个单独的回调函数中定义数组有关,该回调函数是使用 forEach() 与嵌套函数并行定义的。在将变量分配给回调函数中的数组之前,我一直在尝试全局“声明”该变量,但这不起作用。在 c++ 中,我会全局定义一个未实例化的 object(或在 class header 中),然后稍后在某个函数中实例化它,同时在之后的另一个函数中访问它。下面是相关代码,不断返回未定义的变量称为“网格”。请注意,我什至不确定为什么 setPallete(...) 和 update(...) 被实现为嵌套函数(对我来说是一个奇怪的概念)?在此代码的另一个化身中,我将它们实现为“独立”(例如,非嵌套)函数并且一切正常,但在该代码中我没有使用 browserify 进行捆绑,因为我只有一个单一的脚本。所以这可能与此有关。

感谢您的帮助。

let mesh;   //try global definition -- no dice
 
module.exports = function (app) {

    const totalMeshes = 40;
    const subdivisions = 300;
    const numSides = 8;
    const openEnded = false;
    const geometry = createGeometry(numSides, subdivisions, openEnded);
    const container = new THREE.Object3D();
    const lines = newArray(totalMeshes);
 
    ShaderLoader("scripts/Grp3D/lib/shaders/tube.vert", "scripts/Grp3D/lib/shaders/tube.frag", function (vertex, fragment) {
      const baseMaterial = new THREE.RawShaderMaterial({
            vertexShader: vertex,
            fragmentShader: fragment,
            side: THREE.FrontSide,
            extensions: {
              deriviatives: true
           },
           defines: {
              lengthSegments: subdivisions.toFixed(1),
              ROBUST: false,
              ROBUST_NORMALS: false, 
              FLAT_SHADED: true
           },
           uniforms: {
             thickness: { type: 'f', value: 1 },
             time: { type: 'f', value: 0 },
             color: { type: 'c', value: new THREE.Color('#303030') },
             animateRadius: { type: 'f', value: 0 },
             animateStrength: { type: 'f', value: 0 },
             index: { type: 'f', value: 0 },
             totalMeshes: { type: 'f', value: totalMeshes },
             radialSegments: { type: 'f', value: numSides }
           }
        });
    
        lines.map((_, i) => {
           const t = totalMeshes <= 1 ? 0 : i / (totalMeshes - 1);
           const material = baseMaterial.clone();
           material.uniforms = THREE.UniformsUtils.clone(material.uniforms);
           material.uniforms.index.value = t;
           material.uniforms.thickness.value = randomFloat(0.005, 0.0075);
           mesh = new THREE.Mesh(geometry, material);
           mesh.frustumCulled = false; // to avoid ThreeJS errors
           return mesh;
        });
    
        lines.forEach(tmesh => container.add(tmesh));
    });

    return {
        object3d: container,
        update,
        setPalette
    };
    
    // animate in a new color palette
    function setPalette (palette) {
        tweenr.cancel();
        lines.forEach((mesh, i) => {
           const uniforms = mesh.material.uniforms;
           uniforms.color.value.set(palette);
        
           const delay = i * 0.004;
           uniforms.animateRadius.value = 0;
           uniforms.animateStrength.value = 1;
           tweenr.to(uniforms.animateRadius, { value: 1, duration: 0.5, delay, ease: 'epxoOut' });
           tweenr.to(uniforms.animateStrength, { value: 0, duration: 1, delay, ease: 'expoInOut' });
        });
    }
    
    function update (dt) {
       dt = dt / 1000;
       lines.forEach(mesh => {  //undefined when the code runs
            mesh.material.uniforms.time.value += dt;
       });
    }
};

这里有几个问题:

错误const lines = newArray(totalMeshes); 正确 const lines= []; //In Js its not necessary to have a predefined length.

您还需要将数据放在上面的行数组中。

希望我做对了。您可能是指容器变量等,对吗? 我看到的问题是您正在向带有两个参数的 ShaderLoader 添加匿名回调函数。这个函数在 ShaderLoader 的某处被调用。在 ShaderLoader 的范围内,您的变量容器等不再可用。 您在这里使用的是 const,它是块范围的。我发现 an article 很好地解释了它。