【问题标题】:What is the right way for JavaScript functions to accept variablesJavaScript函数接受变量的正确方法是什么
【发布时间】:2011-05-12 15:45:45
【问题描述】:

我是 JS 新手,对这个问题有点困惑,希望你能理解这个问题:

当我想在一个函数中使用来自另一个函数的变量时, 或来自onClick 等事件。 将它从 HTML 或其他函数移动到执行函数的正确方法是什么

工作(还没有..)示例:我有一个包含几个多项选择问题的页面,每个问题都是一个新表单,我希望所有提交按钮都有一个功能,并且在提交时检测表格的名称,所以我应该使用onsubmit="validate(this) 吗?或者有没有更好的方法来获取表单的名称并将其放入 validate 函数中,

一般来说,当我使用function something(){} 并且我希望它从外部获取变量时,我是否必须创建function something(a,b,c){} 还是取决于变量的范围?嗯.. 我什至不确定我是否理解到足以提出一个好的问题,所以任何关于这个主题的文章或教程的参考都会有很大帮助。

【问题讨论】:

    标签: javascript variables global-variables scope


    【解决方案1】:

    因此,JavaScript 的一些核心函数概念应该能够提供帮助。首先也是最重要的:为了处理 DOM 事件,您可能需要依赖库,除非您确实有 0 浏览器兼容性期望。我建议查看jQUery

    也就是说,不显眼的 JavaScript(根据 @Raynos 的回答)是在 JavaScript 中绑定事件的正确方法,并为您提供了很大的灵活性。举个例子:

    function setup_events(){
      var my_form = document.form[0],
          form_name = my_form.name;
      my_form.addEventListener("submit", function(event) {
        console.log( form_name ); // this is retained through the closure.
      });
    }
    

    您可以看到,您可以使用闭包的概念将数据绑定到事件函数,或者在外部作用域从内部作用域返回之后,外部作用域的上下文。现在,当您执行 setup_events 时,您会将 submit 事件与一个内部可以访问外部变量 form_name 的函数绑定。如果您不了解函数作用域,这可能会产生一些令人讨厌的副作用,因此请注意以下代码:

    // XXX : BAD CODE
    function setup_events(){
      var ul = document.getElementsByTagName('ul')[0], // assumes there is a <ul>
          count = 0;
      for ( var li in ul.childNodes ) {
        li.addEventListener('click', function( event ){
          alert( count ++ ); // this will always alert the count of list, not the list position
        }
      }
    }
    

    您可以使用Immediately Invoked Function Expressions 创建必要的闭包以保持正确的状态。因此,要“修复”上述代码,您可以使用以下代码:

    // XXX : BETTER CODE
    /**
     * NOTE: NEVER CREATE FUNCTIONS INSIDE A LOOP
     * this example only shows the immediate solution to the above problem
     * with regard to function scope and closures.
     */
    function setup_events(){
      var ul = document.getElementsByTagName('ul')[0], // assumes there is a <ul>
          count = 0;
      for ( var li in ul.childNodes ) {
        li.addEventListener('click', (function( count ){
          return function ( event ){
            alert( count ); // this will alert the position in the list
          };
        })(count ++))
      }
    }
    

    【讨论】:

    • backbone 很棒,但它不是 DOM 库,而是代码结构库。一个很好的 jQuery 替代品是 ender。 (脊柱的一个很好的替代品是脊柱)。第二个示例也存在在循环中创建函数的BIG 问题。这是缺乏块范围的一个非常常见的例子,但它只是糟糕的代码。
    • @Raynos 我同意在循环中创建函数是糟糕的代码,但不想想出另一个例子来使用。我会注意示例中代码的坏处。
    • 我们需要一个很好的例子来解决块范围的问题:) 我还没有找到一个只是一个陷阱而不是糟糕的代码。
    • 首先,感谢您提供非常详细的回答,但是我不确定我是否全部理解,主要是最后一个示例,您说永远不要在循环中创建函数,但是 eventlistner 正在触发一个函数,我错过了什么?
    • @IlyaD 我表示所表达的模式是一个糟糕的模式,不幸的是,它也是显示块作用域和函数作用域之间差异的唯一方法之一,这是有意义的。这个想法是一个函数可以返回另一个函数(函数是一种数据类型),并且即使在执行完成后,内部函数也可以访问外部函数范围。这是非常强大的,但如果不理解可能会很危险。
    【解决方案2】:

    我会推荐不显眼的 javascript。

    document.form[0].addEventListener("submit", function(event) {
        switch (event.target.name) {
            // switch form name.
        }
    });
    

    当你设计一个通用函数时,你应该考虑你想要接受的参数。

    例如

    function addNumbers(one, two) {
        // add them
    }
    

    被设计为取两个数字。您应该使用您的函数,因为它们设计具有正确的参数。

    <div id="bar"> 3 </div>
    
    ...
    
    (function() {
        // local variables
        var one = 1;
        var two = 2;
    
        // Your getting number 3 globally from the HTML.
        var three = document.getElementById("bar").textContent;
    
        // passed in as parameters
        console.log(addNumbers(one, two)); // 3
        console.log(addNumbers(two, three)); // 5
    
    })();
    console.log(one) // undefined.
    

    【讨论】:

    • 好的,但是说一和二是全局的,如果我只使用function addNumbers() { someUseForOne = one }会有什么区别
    • @llyaD 我们不惜一切代价避免使用全局变量。
    • @Raynos 好的,但是如果它们来自函数外部,它们已经是全局的,还是我弄错了?
    • @llyaD 如果作为参数传入,则不会。如果您的意思是全局的,因为它存储在 DOM 中,那么您可以向 DOM 询问数据。
    • @Raynos 如果您将它们作为参数传递,那么它们不是全局的吗?我才刚刚开始掌握范围的东西......我不认为我理解第二部分,我肯定不是你说的...... :)
    【解决方案3】:

    如果你有这样的功能:

    function something(){
    ...
    }
    

    你仍然可以这样做:

    something(1,2,3);
    

    结果将在函数中的关联对象中,因此您可以像这样访问它们:

    function something(){
        //check for args:
        if(arguments === undefined){...}
        arguments[0]; //which is 1 in our case
        //etc
    }
    

    但对于on{something},您通常必须传递this,或使用某种事件处理程序

    【讨论】:

      【解决方案4】:

      你可以做这样的事情,不完全是,但你明白了:

      function onSubmitClick(){
          if(document.getElementById('choice1').checked==true){
              //store result
          }else if((document.getElementById('choice2').checked==true){
              //store result
          }else if(document.getElementById('choice3').checked==true){
              //store result
          }else if(document.getElementById('choice4').checked==true){
              //store result
          }else{
              //they didn't choose any
      

      【讨论】:

        猜你喜欢
        • 2013-11-16
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多