Javascript:原型(prototype)提供了无限调用对象方法的接口(interface)

标签 javascript this settimeout

我正在寻找满足以下要求的 JavaScript 实现:

  1. 原型(prototype)实现了 nextrun 方法。如果调用 next,则迭代函数 once 被调用一次。如果调用 run,则无限频繁地调用 once(也必须可以通过用户请求中止,但目前未反射(reflect)在源代码中)。
  2. once 接受一个完成参数,一旦完成就会调用该参数。
  3. 迭代函数once原型(prototype)中定义,但可以并且将会被子Child覆盖。
  4. run 中的无限迭代必须是可能的,因此堆栈必须丢失(当 setTimeout 调用函数时会发生这种情况。

我当前的源代码问题:调用了Parent一次,而不是Child的调用。

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="utf-8" />
    <title>JS test</title>
    <script type="text/javascript">
      function write(msg) {
        var t = document.createTextNode(msg);
        var li = document.createElement("li");
        li.appendChild(t);
        document.querySelector("ul").appendChild(li);
      }

      var Parent = function () {
        var running = 0;

        var run = function () {
          running = Infinity;
          invokeNextIter();
        };

        var next = function () {
          running = 1;
          invokeNextIter();
        };

        var invokeNextIter = function () {
          if (running > 0) {
            running -= 1;
            setTimeout(function () { once(invokeNextIter); }, 1);
          }
        };

        var once = function (done) {
          var time = Math.random() * 3 + 1;
          write(time + " sec");
          setTimeout(done, time * 1000);
        };

        return {
          run: run,
          once: once
        };
      };

      var Child = function () {
        var once = function (done) {
          write("2 sec as always");
          setTimeout(done, 2000);
        };

        var p = new Parent();
        return Object.create(p, { once : once });
      };

      function main() {
        var c = new Child();
        c.run();
      }
    </script>
  </head>
  <body onload="main()">
    <ul>
    </ul>
  </body>
</html>

无法使用 Function.prototype.bind 或相关技术运行它。任何帮助感激不尽😎

最佳答案

好吧,就您的情况而言,ParentChild 之间唯一不同的函数是您的 once() 函数。

所以你必须从你的Parent类开始,构建核心,然后你将实例方法添加到Parentchild,以覆盖 once() 函数。

我们将使用原型(prototype)继承。规则是您可以为使用 new 关键字初始化的任何对象创建原型(prototype),其中包括 native JavaScript 对象。

  function write(msg) {
     var t = document.createTextNode(msg);
     var li = document.createElement("li");
     li.appendChild(t);
     document.querySelector("ul").appendChild(li);
   }

   var Parent = function(){
     //Retrieve context
     var self = this;

     var running = 0
     //Create a `run` function which will refer to the current context
     self.run = function(){
       running = Infinity;
       invokeNextIter();
     }

     //Declare our private function
     var next = function () {
        running = 1;
        invokeNextIter();
      };

     var invokeNextIter = function () {
        if (running > 0) {
          running -= 1;
          setTimeout(function () {
            //Call once method which is in the prototype of the current context
            self.once(invokeNextIter);
          }, 1);
        }
      };
   }

   //Add a "once" instance method to Parent
   Parent.prototype.once = function(done){
     var time = Math.random() * 3 + 1;
     write(time + " sec");
     setTimeout(function(){
       done();
     }, time * 1000);
   }


   //Create our Child 'class'
   var Child = function(){

   }

   //Declare Child as a subclass of the first
   Child.prototype = new Parent();

   //Add a "once" instance method to Child and override the "once" parent method
   Child.prototype.once = function(done){
     write("1.5 sec as always");
     setTimeout(function(){
       done();
     }, 1500);
   }


   function main(){
     // Create instances and see the overridden behavior
     var c = new Child();
     var p = new Parent();
     //c.run() will call child once() method
     c.run();
     //p.run() will call parent once() method
     p.run();
   }

在这里,您可以看到 self.run()self.once()Self 变量将引用当前实例。

关于Javascript:原型(prototype)提供了无限调用对象方法的接口(interface),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32203313/

相关文章:

javascript - IE 在全屏模式下无法滚动

javascript - 如何将 jquery 插件 (HTML) 包含到 JS 代码中

javascript - 为什么更改 InnerHtml 时此 div 会下拉?

javascript - 为什么Capybara/Rspec在Sweet Alert Modal中找不到按钮,但have_selector返回true?

javascript - 为什么调用带有括号的方法,例如。 (obj.func)(),仍然设置 `this` 吗?

jquery延迟和setTimeout

python - 如果2秒内找不到元素如何让驱动程序退出

javascript:在链中,如何获取前一个数组的大小?

properties - Kotlin:返回 "this"的默认 setter

javascript - setTimeout 花费的时间比应该的长