javascript - 嵌套类的范围问题

标签 javascript oop timer scope mootools

我无法访问嵌套类的方法。这是我到目前为止所尝试过的。主要问题是调用 TimerTask.execute()。该错误表明任务未定义。

Uncaught TypeError: undefined is not a function

程序应显示计时器运行十次的增量数字。

var TimerTask = new Class({
  initalize: function (options) {
    this.counter = options.counter;
    this.run = options.run;
    this.onComplete = options.complete;
    this.done = false;
  },
  execute : function() {
    var me = this;
    this.counter--;
    if (this.done === false || this.counter <= 0) {
      this.done = true;
      me.onComplete.call(me);
    } else {
      me.run.call(me);
    }   
  }
});

var Timer = new Class({
  initialize: function (options) {
    this.id = 0;
    this.running = true;
    this.count = 0;
    this.delay = options.delay || 1000;
    this.tasks = options.tasks || [];
  },
  start: function () {
    var me = this;
    me.id = setInterval(function tick() {
      if (!me.running) return;
      for (var i = 0; i < me.tasks.length; i++) {
        me.tasks[i].execute();
      }
      me.count++;
    }, this.delay);
  },
  pause: function pause() {
    this.running = false;
    return this;
  },
  run: function run() {
    this.running = true;
    return this;
  },
  stop: function stop() {
    clearInterval(this.id);
    this.stopped = true;
    return this;
  },
  schedule: function (task) {
    this.tasks.push(task);
  }
});

var i = 0;
var t1 = new Timer({
  delay: 1000,
  tasks: [
    new TimerTask({
      run: function () {
        document.getElementById('output').innerHTML = parseInt(i++, 10);
      },
      onComplete: function () {
        alert('DONE!');
      },
      counter: 10
    })]
});

t1.start();
<script src="//cdnjs.cloudflare.com/ajax/libs/mootools/1.5.0/mootools-core-full-compat.min.js"></script>
<div id="output"></div>

最佳答案

噢,哇。不敢相信没有人发现 TimerTask 中的拼写错误。难怪我一直得到原型(prototype)而不是实例。我拼写了“initialize”,没有第三个“i”...

无论如何,我解决了这个问题并且代码很棒。

注意:我用它作为我的计时器的基础 -- https://gist.github.com/NV/363465

var TimerTask = new Class({
    initialize: function (options) {
        this.counter = options.counter || 0;
        this.run = options.run;
        this.onComplete = options.onComplete;
        this.active = true;
        this.isInfinite = this.counter === 0;
    },
    execute: function () {
        if (!this.isInfinite && this.counter === 0) {
            this.active = false;
            if (this.onComplete !== undefined) {
                this.onComplete();
            }            
        } else {
            this.run();
            if (!this.isInfinite) {
                this.counter--;
            }
        }
    },
    isActive: function () {
        return this.active;
    }
});

var Timer = new Class({
    initialize: function (options) {
        this.id = 0;
        this.running = true;
        this.count = 0;
        this.delay = options.delay || 1000;
        this.tasks = options.tasks || [];
        Timer.all.push(this);
    },
    start: function () {
        var me = this;
        me.id = setInterval(function tick() {
            if (!me.running) return;
            for (var i = 0; i < me.tasks.length; i++) {
                var task = me.tasks[i];
                if (task.isActive()) {
                    task.execute();
                } else {
                    console.log('Task is complete...');
                }
            }
            me.count++;
        }, this.delay);
    },
    pause: function pause() {
        this.running = false;
        return this;
    },
    run: function run() {
        this.running = true;
        return this;
    },
    stop: function stop() {
        clearInterval(this.id);
        this.stopped = true;
        return this;
    },
    schedule: function (task) {
        this.tasks.push(task);
    }
});

Timer.extend({
    all : [],
    pause : function pause() {
        var all = Timer.all;
        for (var i = 0; i < all.length; i++) {
            all[i].pause();
        }
        return all;
    },
    run : function run() {
        var all = Timer.all;
        for (var i = 0; i < all.length; i++) {
            all[i].run();
        }
        return all;
    },
    stop : function stop() {
        var all = Timer.all;
        for (var i = 0; i < all.length; i++) {
            all[i].stop();
        }
        return all;
    }
});

function print(id, value) {
    document.getElementById(id).innerHTML = value;
}

var i = 0;
var t1 = new Timer({
    delay: 100,
    tasks: [
    new TimerTask({
        run: function () {
            print('output1', String.fromCharCode(65 + i));
        },
        onComplete: function () {
            console.log('Task 1 complete...');
        },
        counter: 26
    }),
    new TimerTask({
        run: function () {
            print('output2', parseInt(i++, 10));
        }
    })]
});

t1.start();

// After 4 seconds, stop all timers.
setTimeout(function() {
    Timer.stop();
}, 4000);
<script src="//cdnjs.cloudflare.com/ajax/libs/mootools/1.5.0/mootools-core-full-compat.min.js"></script>
<div id="output1"></div>
<div id="output2"></div>

关于javascript - 嵌套类的范围问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26567808/

相关文章:

oop - 如何在dart中实现继承?

java - 如何创建一个对象来启动一个与我的程序一起运行的线程?

ios - 程序化转场后自动触发的 Action

C# 在 10 秒后禁用控件的最简单方法是什么?计时器还是秒表?

javascript - 在 Three.JS 中向 Material 贴图添加纹理时出现 WebGL 警告

javascript - 重组超出最大更新深度

javascript - 从 firefox 扩展中检索网站的 favicon url

javascript - 如何以 Angular 将错误添加到表单验证错误列表中?

php - 从同一类中的静态方法访问另一个方法中的变量

c++ - 写入特定数据成员的内存时出错