javascript对象使用相同的覆盖变量

时间:2014-11-21 16:43:51

标签: javascript object webgl

我有一个我正在使用的javascript对象。我有一个我希望保持原样的顶点数组(var称为顶点)。在对象中我有一个setScalar()方法,它将采用这个顶点矩阵并应用一个标量(jus一个简单的for循环乘法每个值)。当我创建一个新对象时,我应用我的标量但是当我创建一个新对象时我不引用原始顶点数组似乎将标量应用于先前对象中使用的缩放顶点。

这里是verts数组:

var verts = [
            // Front face
            -1.0, -1.0,  1.0,
             1.0, -1.0,  1.0,
             1.0,  1.0,  1.0,
            -1.0,  1.0,  1.0,

            // Back face
            -1.0, -1.0, -1.0,
            -1.0,  1.0, -1.0,
             1.0,  1.0, -1.0,
             1.0, -1.0, -1.0,

            // Top face
            -1.0,  1.0, -1.0,
            -1.0,  1.0,  1.0,
             1.0,  1.0,  1.0,
             1.0,  1.0, -1.0,

            // Bottom face
            -1.0, -1.0, -1.0,
             1.0, -1.0, -1.0,
             1.0, -1.0,  1.0,
            -1.0, -1.0,  1.0,

            // Right face
             1.0, -1.0, -1.0,
             1.0,  1.0, -1.0,
             1.0,  1.0,  1.0,
             1.0, -1.0,  1.0,

            // Left face
            -1.0, -1.0, -1.0,
            -1.0, -1.0,  1.0,
            -1.0,  1.0,  1.0,
            -1.0,  1.0, -1.0
        ];

以下是我在对象中设置它的方法。

//Cube object
    function Cube(name, vertices, cubeVertInd, color, scale, positionX, positionY, positionZ) 
    {
        this.name = name;
        this.vertices = vertices;
        this.cubeVertexIndices = cubeVertInd;
        this.positionX = positionX;
        this.positionY = positionY;
        this.positionZ = positionZ;
        this.setColor(color);
        this.setScale(vertices, scale);
    }

这是setScale方法

Cube.prototype.setScale = function(vertices, scale) 
    {
        var length = vertices.length;
        for( var i = 0; i < length; i++)
        {
            vertices[i] *= scale; 
        }
    }

我知道这就是发生的事情,因为当我在webgl中使用它时,我会根据我制作第一个对象的大小来获得不同的大小。如果我将对象设置为比例2,则将下一个对象设置为缩放0.1,即使原始顶点全是1,我得到0.2,因为第二个对象缩放。这表明我在第一个对象中设置的比例正在使用而不是顶点

3 个答案:

答案 0 :(得分:1)

您必须克隆vertices数组,否则它始终是对原始vert数组的引用。

试试这个:

//Cube object
    function Cube(name, vertices, cubeVertInd, color, scale, positionX, positionY, positionZ) 
    {
        // make a copy of the vertices
        vertices = vertices.slice();

        this.name = name;
        this.vertices = vertices;
        this.cubeVertexIndices = cubeVertInd;
        this.positionX = positionX;
        this.positionY = positionY;
        this.positionZ = positionZ;
        this.setColor(color);
        this.setScale(vertices, scale);
    }

答案 1 :(得分:0)

如果您仅将setScale()用于此目的,则可以使用Array.prototype.map()方法并删除函数setScale()

在这种情况下,会创建另一个新对象,缩放并分配给this.vertices

function Cube(name, vertices, cubeVertInd, color, scale, positionX, positionY, positionZ) 
    {
        this.name = name;
        this.vertices = vertices.map(function(value){
                             return value*scale;
                        });
        this.cubeVertexIndices = cubeVertInd;
        this.positionX = positionX;
        this.positionY = positionY;
        this.positionZ = positionZ;
        this.setColor(color);
    }

答案 2 :(得分:0)

这是对a similar thing happens when i set the positions is there anyway I can make these unique to each iteration of the object?

的回答

这个问题的一般解决方案是拥有一个克隆函数,它可以返回一个对象的克隆(不是引用)。因此,假设您有一个基础对象{verts: [1,2,3..], positionX: 5, ...}等,那么在创建新对象时您想要做的是newObj = clone(baseObj), then newObj.setScale(-1)

所述克隆功能的一个实现:

var clone = function(obj,visited){
    if (obj === null || typeof(obj) !== "object"){ // primitives and functions
        return obj;
    }
    visited = visited || [];

    if (visited.indexOf(obj)===-1){ // enable cloning objects with circular references at cost of linear search;
        visited.push(obj);
        if (obj instanceof RegExp){
            return new RegExp(obj);
        } else if (obj instanceof Date){
            return new Date(obj);
        } else if (Array.isArray(obj)){ // the [[Class]] of arrays can only be set by using Array constructor or [];
            var newObj = [];
        } else if (obj.constructor !== undefined){
            newObj = Object.create(obj.constructor.prototype);
        } else {
            throw new TypeError("How to clone object: "+obj+" is undefined.", obj);
        }

    } else { // if object already seen/ circular reference; just return reference to it
        return obj;
    }

    for(var key in obj) { // recursive call itself;
        if(obj.hasOwnProperty(key)) {
            newObj[key] = clone(obj[key],visited);
        }
    }
    return newObj;
};