Javascript 关于函数中参数和document.writeln的范围

Javascript 关于函数中参数和document.writeln的范围,javascript,arguments,Javascript,Arguments,我正在读“JavaScripts的好部分”(道格拉斯·克罗克福德)。很好。 我不能理解下面的代码。它工作正常。但我不明白它是如何工作的。 关于此代码有5个问题 参数值(我在注释中将它们检查为[A]、[B]) document.writeln在函数中不起作用(即不显示任何内容)的原因(我在注释中将测试位置选为[C],[D]) 此代码中切片的结果(在[A]、[B]中) 变量args的值(在[A]、[B]中) document.writeln显示“未定义”的原因(在注释[E]中) 在展示代码之后,我将

我正在读“JavaScripts的好部分”(道格拉斯·克罗克福德)。很好。 我不能理解下面的代码。它工作正常。但我不明白它是如何工作的。 关于此代码有5个问题

  • 参数值(我在注释中将它们检查为[A]、[B])
  • document.writeln在函数中不起作用(即不显示任何内容)的原因(我在注释中将测试位置选为[C],[D])
  • 此代码中切片的结果(在[A]、[B]中)
  • 变量args的值(在[A]、[B]中)
  • document.writeln显示“未定义”的原因(在注释[E]中)
  • 在展示代码之后,我将进一步解释

    var myTest = {};
    
    Function.prototype.method = function(name, func) {
      if(!this.prototype[name])
      {
        this.prototype[name]=func;
      }
    };
    
    Function.method('bind', function(that) {
      var method = this,
      slice = Array.prototype.slice,
      args = slice.apply(arguments, [1]);    //[A] value of arguments and args 
    
      //-------------------------------
      //[C] following document.writeln do not work. why?
      document.writeln("<C>arguments[0]:", arguments[0]);
      document.writeln("<C>arguments[1]:", arguments[1]);
      document.writeln("<C>args:",args);
      myTest.str1 = 1;
      myTest.str2 = "ABC";
      document.writeln("<C>str1:", myTest.str1);
      document.writeln("<C>str2:", myTest.str2);
      //-------------------------------
    
      return function(){
    
         //-------------------------------
         //[D] following document.writeln do not work. why?
         document.writeln("<D>arguments[0]:", arguments[0]);
         document.writeln("<D>arguments[1]:", arguments[1]);
         document.writeln("<D>args:",args);
         myTest.str3 = 2;
         myTest.str4 = "DEF";
         document.writeln("<D>str3:", myTest.str3);
         document.writeln("<D>str4:", myTest.str4);
         //-------------------------------
    
          return method.apply(that, args.concat(slice.apply(arguments, [0])));    //[B] value of arguments and args 
        };
      });
    
    var x= function(){
      return this.value;
    }.bind({value:666});
    
    //-------------------------------
    document.writeln("str1:", myTest.str1, "<br/>");   //[E]show undefined. why?
    document.writeln("str2:", myTest.str2, "<br/>");   //[E]show undefined. why?
    document.writeln("str3:", myTest.str3, "<br/>");   //[E]show undefined. why?
    document.writeln("str4:", myTest.str4, "<br/>");   //[E]show undefined. why?
    //-------------------------------
    
    alert(x());    //666 -> no problem
    
    现在,我想知道[C],[D]中参数的实际值,数组的内容

    使用JSON.stringify(arguments[0]),我最终得到了参数的实际值

    [C]arguments[0]:{"value":666}
    
    这是我真正想要的。 [C] 参数[1],[D]参数[0],[D]参数[1]没有值。所以它们是“未定义的”,对吗

    现在,我想知道“args=slice.apply(arguments[1]);”在[A]中的作用

    args = slice.apply(arguments, [1]);
    
    正如我所知,slice返回数组的副本。因为我们使用apply,所以slice使用的参数如下,[1]作为参数数组。此时,参数只有一项{“value”:666“}。slice(start,end)返回从“start”开始并以“end”结束的数组副本。然后,在本例中,slice.apply(参数,[1])必须返回从1开始的参数副本。但我们知道,参数只有1项,所以参数[1]不存在。(参数[0],{value:666}存在。)那么这是如何工作的?args是未定义的。这是做什么的?有什么我忽略的吗

    在[B]中,它返回“method.apply(即args.concat(slice.apply(arguments,[0]))”;“

    在这里,[0]是参数数组。0..为什么是零?参数是未定义的。嗯…那么这将返回参数[0]?即{value:666}?并发出警报“666”


    我明白了

    [A]中的参数是绑定函数的参数

    [B]中的参数是x函数的参数

    对吧?

    现在有一个(也许是最后一个)问题^^ 当我调用document.writeln.bind(document,“TEST”)时,Function.method('bind',Function(that))中的'that'是什么

    “那”是文档?还是“那”是[文档,“测试”]

    …这是您的问题。您没有覆盖现有函数-并且已经存在(并且具有与您定义的函数相同的结果,但没有日志记录)。这样,您就不会使用自定义实现覆盖它,并且不会执行任何
    文档。writeln
    调用或
    myTest
    分配

    出于测试目的,您可以删除if条件,它将起作用。一旦您在输出中看到发生了什么,您应该能够自己回答其他问题


    现在,我想知道[C],[D]中参数的实际值,数组的内容

    这里只讨论了一个对象:
    {value:666}
    :-)您可以使用以下命令输出:


    如果你(还)不习惯使用控制台,你同样可以使用
    document.writeln.bind(document,

    我修复了一些拼写错误,我在我的帖子中添加了额外的问题。我想知道[C],[D]中参数的真实内容我在帖子中添加了额外的问题^;;我想知道为什么[1],[0]在应用函数中使用可能是最后一个问题…^^我在文章末尾补充了这一点。(当我调用document.writeln.bind(document,“TEST”)时,那是什么?)谢谢^^^我还有其他问题。正如你所说,Function.prototype.method已经存在。那么,在我看来,Function.method('bind',Function(that))必须使用“已经存在”来工作“Function.method.但它不起作用。当然,当我删除if condition document.writeln时效果很好。是的,
    Function.method('bind',…)
    让原始方法不受影响。已经存在的函数确实起作用-你最终会像预期的那样提醒666。你是对的。^;;我在我的帖子中添加了其他问题。我想知道为什么[1],[0]用于应用函数I god it.^^^^在[A]中的参数是bind的参数,[B]中的参数是x的参数。对吗?我还有其他(可能是最后一个)问题…^^^^我在文章末尾补充了这个问题。(当我调用document.writeln.bind(document,“TEST”),那是什么?)
    that
    参数是传递
    文档
    的地方,这样它就变成了“在
    writeln
    函数中”-因此它的行为与方法调用
    document.writeln(…)
    :-)
    args = slice.apply(arguments, [1]);
    
    return method.apply(that, args.concat(slice.apply(arguments, [0])));
    
    Function.prototype.method = function(name, func) {
        if(!this.prototype[name])
    
    document.writeln("<C>arguments[0]:", JSON.stringify(arguments[0]));
    …
    
    var logger = console.log.bind(console, "Here:");
    logger(); // Here:
    logger(5); // Here: 5
    logger({value:666}); // Here: {value: 666}