Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/463.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 在类方法中将变量传递给函数_Javascript_Es6 Class - Fatal编程技术网

Javascript 在类方法中将变量传递给函数

Javascript 在类方法中将变量传递给函数,javascript,es6-class,Javascript,Es6 Class,我有一个我正试图写的类,看起来像下面的 当我运行该类时,我得到一个错误: Audio.js:53未捕获引用错误:未定义缓冲长度 我认为这是因为bufferLength在drawCanvas函数中不可用 我曾尝试添加this关键字,但没有效果 如何使此类方法中的函数可以使用这些变量 export const LINE_COLORS = ['rgba(255, 23, 204, 0.5)', 'rgba(130, 23, 255, 0.5)']; // The dimensions of the

我有一个我正试图写的类,看起来像下面的

当我运行该类时,我得到一个错误:

Audio.js:53未捕获引用错误:未定义缓冲长度

我认为这是因为
bufferLength
drawCanvas
函数中不可用

我曾尝试添加
this
关键字,但没有效果

如何使此类方法中的函数可以使用这些变量

export const LINE_COLORS = ['rgba(255, 23, 204, 0.5)', 'rgba(130, 23, 255, 0.5)'];

// The dimensions of the current viewport
// - Used to set canvas width & height
export const PAGE_DIMENSIONS = {
  width: window.innerWidth || document.documentElement.clientWidth || document.body.clientWidth,
  height: window.innerHeight || document.documentElement.clientHeight || document.body.clientHeight,
};

class AudioEngine {
  constructor(params) {
    this.params = params;
    this.audio = new Audio();
    this.ctx = new (window.AudioContext || window.webkitAudioContext)();
    this.analyser = this.ctx.createAnalyser();
    this.source = this.ctx.createMediaElementSource(this.audio);
    this.dataArray = new Uint8Array(this.analyser.frequencyBinCount);
    this.bufferLength = this.analyser.frequencyBinCount;

    this.canvas = document.getElementById(params.waveform);

    this.onInit();
  }

  onInit() {
    this.ConfigAudio();
    this.DrawAudioWave();
  }

  ConfigAudio = () => {
    this.audio.src = this.params.stream;
    this.audio.controls = false;
    this.audio.autoplay = false;
    this.audio.crossOrigin = 'anonymous';
    this.analyser.smoothingTimeConstant = 0.6;
    this.source.connect(this.ctx.destination);
    this.source.connect(this.analyser);
    this.analyser.fftSize = 2048;
    this.analyser.getByteFrequencyData(this.dataArray);

    document.body.appendChild(this.audio);
  };

  DrawAudioWave = () => {
    // Bind to the context
    const canvasCtx = this.canvas.getContext('2d');

    function drawCanvas() {
      // We always start the drawing function by clearing the canvas. Otherwise
      // we will be drawing over the previous frames, which gets messy real quick
      canvasCtx.clearRect(0, 0, PAGE_DIMENSIONS.width, PAGE_DIMENSIONS.height);
      requestAnimationFrame(drawCanvas);
      const sliceWidth = (PAGE_DIMENSIONS.width * 1.0) / bufferLength;
      // Create a new bounding rectangle to act as our backdrop, and set the
      // fill color to black.
      canvasCtx.fillStyle = '#000';
      canvasCtx.fillRect(0, 0, PAGE_DIMENSIONS.width, PAGE_DIMENSIONS.height);

      // Loop over our line colors. This allows us to draw two lines with
      // different colors.
      LINE_COLORS.forEach((color, index) => {
        let x = 0;
        // Some basic line width/color config
        canvasCtx.lineWidth = 2;
        canvasCtx.strokeStyle = color;

        // Start drawing the path
        canvasCtx.beginPath();
        for (let i = 0; i < bufferLength; i++) {
          // We offset using the loops index (stops both colored lines
          // from overlapping one another)
          const v = dataArray[i] / 120 + index / 20;
          // Set the Y point to be half of the screen size (the middle)
          const y = (v * PAGE_DIMENSIONS.height) / 2;

          if (i === 0) {
            canvasCtx.moveTo(x, y);
          } else {
            canvasCtx.lineTo(x, y);
          }

          x += sliceWidth;
        }
        canvasCtx.lineTo(canvas.width, canvas.height / 2);
        canvasCtx.stroke();
      });
    }
    drawCanvas();
  };

  audioToggle = () => (this.audio.paused ? this.audio.play() : this.audio.pause());
}

export default AudioEngine;
export const LINE_COLORS=['rgba(255,23204,0.5)''rgba(130,23255,0.5)';
//当前视口的尺寸
//-用于设置画布宽度和高度
导出常量页面\ U维度={
宽度:window.innerWidth | | | document.documentElement.clientWidth | | document.body.clientWidth,
高度:window.innerHeight | | | document.documentElement.clientHeight | | | document.body.clientHeight,
};
类音频引擎{
构造函数(参数){
this.params=params;
this.audio=新音频();
this.ctx=new(window.AudioContext | | window.webkitadiocontext)();
this.analyzer=this.ctx.createAnalyzer();
this.source=this.ctx.createMediaElementSource(this.audio);
this.dataArray=新UINT8阵列(this.analyzer.frequencyBinCount);
this.bufferLength=this.Analyzer.frequencyBinCount;
this.canvas=document.getElementById(参数波形);
这个。onInit();
}
onInit(){
这是ConfigAudio();
这个。DrawAudioWave();
}
ConfigAudio=()=>{
this.audio.src=this.params.stream;
this.audio.controls=false;
this.audio.autoplay=false;
this.audio.crossOrigin='anonymous';
此.Analyzer.smoothingTimeConstant=0.6;
this.source.connect(this.ctx.destination);
本源连接(本分析仪);
this.analyzer.fftSize=2048;
this.analyzer.getByTefFrequencyData(this.dataArray);
document.body.appendChild(this.audio);
};
DrawAudioWave=()=>{
//与上下文绑定
const canvasCtx=this.canvas.getContext('2d');
函数drawCanvas(){
//我们总是通过清除画布来启动绘图功能,否则
//我们将在之前的画面上画图,很快就会变得一团糟
canvasCtx.clearRect(0,0,页面尺寸。宽度,页面尺寸。高度);
requestAnimationFrame(drawCanvas);
const sliceWidth=(PAGE_DIMENSIONS.width*1.0)/bufferLength;
//创建一个新的边框作为背景,并设置
//填充颜色为黑色。
canvasCtx.fillStyle='#000';
canvasCtx.fillRect(0,0,页码尺寸.宽度,页码尺寸.高度);
//在我们的线颜色上循环。这允许我们用颜色画两条线
//不同的颜色。
LINE_COLORS.forEach((颜色,索引)=>{
设x=0;
//一些基本的线宽/颜色配置
canvasCtx.lineWidth=2;
canvasCtx.strokeStyle=颜色;
//开始绘制路径
canvasCtx.beginPath();
for(设i=0;i(this.audio.pause?this.audio.play():this.audio.pause());
}
导出默认音频引擎;

requestAnimationFrame将使用全局上下文绑定调用drawCanvas,因此不会定义此.bufferLength。最简单的解决方案是利用箭头函数使其变得简单

如果看一下如何定义类的方法,它们使用的是箭头函数。这正是为了避免重新绑定当前的
This
的问题。您应该仔细阅读JavaScript的内容和作用域,以便更好地理解为什么您的代码不能像预期的那样工作

两种解决方案都需要
drawCanvas->this.drawCanvas

(A) 在将drawCanvas的上下文传递给requestAnimationFrame之前绑定它:

requestAnimationFrame(drawCanvas.bind(this))

或者(B)利用词汇范围:

requestAnimationFrame(()=>drawCanvas())

“词法”作用域是从“文本”派生的作用域,即相对于其他作用域定义箭头函数的位置。非词汇作用域使用调用者函数确定绑定上下文

您还可以使用
.bind
或将其更改为箭头函数,将
drawCanvas
函数本身绑定到适当的范围

进一步阅读

  • (将示例中的
    setTimeout
    替换为
    requestAnimationFrame

我注意到您的代码中还有其他内容。您正在调用函数主体之前的
requestAnimationFrame
,这意味着您可以拥有竞争条件。您应该在函数体执行后将请求移动到,或者考虑清除/取消以前的请求。