了解javascript变量处理和引用,尤其是canvas ImageArray和数组赋值

了解javascript变量处理和引用,尤其是canvas ImageArray和数组赋值,javascript,html5-canvas,Javascript,Html5 Canvas,考虑以下代码: var deSaturated = deSaturate(greyscaleCtx.getImageData(0, 0, canvasWidth, canvasHeight)); imageData来自getImageData画布函数 function deSaturate (imageData) { var theData = imageData.data; var dataLength = theData.l

考虑以下代码:

var deSaturated = deSaturate(greyscaleCtx.getImageData(0, 0, canvasWidth, canvasHeight));
imageData来自getImageData画布函数

function deSaturate (imageData) {
                var theData = imageData.data;

                var dataLength = theData.length;
                var i = dataLength-1;
                var lightLevel;
                // Iterate through each pixel, desaturating it
                while ( i >= 0) {
                    // To find the desaturated value, average the brightness of the red, green, and blue values

                    theData[i] = theData[i+1] = theData[i+2] = (theData[i] + theData[i + 1] + theData[i + 2]) / 3;

                    // Fully opaque
                    theData[i+3] = 255;
                    // returning an average intensity of all pixels.  Used for calibrating sensitivity based on room light level.
                    lightLevel += theData[i]; //combining the light level in the samefunction
                    i -= 4;

                }

                imageData.data = theData; //bring back theData into imageData.data - do I really need this?


                var r = [lightLevel/dataLength,imageData]
                return r;
            }
在编写和优化这段代码的过程中,我发现我并不真正理解js是如何处理例如“theData”变量的。使用它只是引用imageData.data的一种简单方式,在这种情况下,我最终不需要以下代码:

imageData.data = theData
但是,我是否需要支付性能降低(大量DOM I/O)的费用

或者正在执行
data=imageData.data
实际复制原始数组(表示为uint8clampedaray),然后我必须将修改后的数据重新分配给
imageData.data

我猜这是基本的javascript,但我在MDN和其他开发人员资源中发现了相互矛盾的代码示例,我真的很想正确理解这一点


谢谢你的帮助

在javascript中,分配
数组
对象
只分配对该数组或对象的引用-它不会复制数据。只有在物理上创建一个新数组,并通过该数组复制数据,或调用某个专门为您设计的函数时,才会进行复制

因此,如果
imageData.data
是一个
数组
,那么将其分配给
数据
只会创建一个引用相同数据的快捷方式。它不会生成数据的新副本。因此,在修改数据所指向的数据后,您不必将其重新分配给
imageData.data
,因为数据只有一个副本,而
data
imageData.data
都指向同一个数据副本

因此,在直接回答您的问题时,这句话是不必要的:

imageData.data = theData;
刚刚运行了一个快速测试:

    var idata = ctx.getImageData(0,0,300,300);
    var data = idata.data;
    for(var i=0;i<data.length;i++){
        data[i]=0;
    }

    ctx.putImageData(idata,0,0);
var idata=ctx.getImageData(0,0300);
var数据=idata.data;

对于(var i=0;我认为,
imageData.data=theData
行是不必要的。@IanKuca:不,不是。它似乎是imageData.data的一个非常清晰和明显的别名(7个字符对14个字符).然而,它是一个主机对象,可能有一个getter和setter而不是一个简单的属性,
数据
不是一个普通的
数组
,而是一个非常类似于类型化数组的数组。因此我认为这需要更多的研究,而不是。
数据
属性甚至是只读的,因此该行完全没有用处:谢谢!再等等她的小东西-因为我不需要改变图片,我只需要使用数组来计算绘制到画布上的视频中的运动。我得到了另一张图片(实际上是一帧)以60 fps或类似速度。是否仍然需要putImageData?如果我只使用imageData而不从画布恢复更多信息?是的,如果您不关心画布本身的更新,则无需putImageData。