【问题标题】:Javascript call nested functionJavascript调用嵌套函数
【发布时间】:2012-02-07 17:25:55
【问题描述】:

我有以下代码:

function initValidation()
{
    // irrelevant code here
    function validate(_block){
        // code here
    }
}

有什么方法可以在initValidation() 函数之外调用validate() 函数?我试过调用validate(),但我认为它只在父函数内部可见。

【问题讨论】:

  • 当涉及到函数时,大括号之间的任何内容都无法被外部访问,除非可以访问,例如通过点符号属性赋值或 return 语句。您可以在外部函数外部或内部进行赋值,但无论哪种方式都需要外部操作,最少需要运行一次外部函数。

标签: javascript nested-function


【解决方案1】:

作为 Esailija 答案的一个小变化,我这样做了:

function createTree(somearg) {
    function validate(_block) {
        console.log( "test", _block );
    }
    if (somearg==="validate") { return validate; } // for addNodes

    // normal invocation code here
    validate(somearg);
}

function addNodes() {
    const validate = createTree("validate");
    //...
    validate( "hello" );
}

createTree("create");
addNodes();
//validate("illegal");

所以 validate() 现在在 createTree() 和 addNodes() 之间完美共享,并且对外界完全不可见。

【讨论】:

    【解决方案2】:
    function initValidation()
    {
       
        function validate(_block){
            console.log(_block)
            // code here
        }
        // you have to call nested function
        validate("Its Work")
    }
    
    // call initValidation function
    initValidation()
    

    【讨论】:

    • 虽然此代码可能会回答问题,但提供有关它如何和/或为什么解决问题的额外上下文将提高​​答案的长期价值。
    【解决方案3】:

    在父函数之外创建一个变量,然后在父函数中将你需要的函数存储在变量中。

    Var Store;
    Function blah() {
    
        Function needed() {
            #
        }
    
       Store = needed;
    }
    

    【讨论】:

      【解决方案4】:

      函数定义:

      function initValidation() {
         // code here
         function validate(_block){
           // code here
           console.log(_block);
         }
         return validate;
      }
      

      如下调用:

      initValidation()("hello");
      

      【讨论】:

        【解决方案5】:

        我知道这个帖子已经存在了很长一段时间,但我想我也会留下我的 0.02$ 来讨论如何从其范围之外调用内部函数(可能对某人有益)。

        请注意,在任何地方,都应该考虑一个更好的设计决策,而不是一些会在以后反噬你的骇人听闻的解决方法

        使用function expressions 代替function statements 并使用global scope 怎么样。

              var innerFn;
            
              function outerFn() {
                innerFn = function(number) {
                  return number ** 2;
                }
              }
            
              outerFn();
              console.log(innerFn(5));
        
              // if there's more complex code around and you could write this defensively
        
              if (typeof innerFn !== 'undefined') {
                console.log(`we are squaring the number 5 and the result is: ${innerFn(5)}`);
              } else {
                console.log('function is undefined');
              }

        或者,您可以使用closures

        function outer() {
          // initialize some parameters, do a bunch of stuff
          let x = 5, y = 10;
        
          function inner() {
            // keeps references alive to all arguments and parameters in all scopes it references
            return `The arithmetic mean of the 2 numbers is: ${(x + y) / 2}`;
          }
          
          return inner;
        }
        
        innerFn = outer(); // get a reference to the inner function which you can call from outside
        console.log(innerFn());

        【讨论】:

          【解决方案6】:

          此调用将返回函数语句,即函数验证。 所以你可以在第一次调用之后直接调用。

          function initValidation() {
            // irrelevant code here
            return function validate(_block) {
              // code here
            }
          }
          
          initValidation()();
          

          【讨论】:

            【解决方案7】:

                function initValidation()
                {
                    // irrelevant code here
                    function validate(_block){
                        console.log( "test", _block );
                    }
                
                    initValidation.validate = validate;
                }
            
                initValidation();
                initValidation.validate( "hello" );
                //test hello

            【讨论】:

            • 我认为这个答案是真正回答问题的答案。谢谢!
            • 由于某种原因,当时我还没有看到这个答案。我已将其更新为可接受的答案,因为这显然是最好的方法。
            • @yuno 请不要在别人的答案上“打码”。
            • 我不明白我们为什么打电话给initValidation();。有人可以帮我吗?
            • @HarkiratSaluja - 尝试删除 initValidation(),你会得到一个错误。原因首先你需要通过调用initValidation()来初始化initValidation.validate()
            【解决方案8】:

            我知道这是一篇旧文章,但如果您希望创建一组您希望使用的实例,以重用代码,您可以执行以下操作:

            "use strict";
            // this is derived from several posts here on SO and ultimately John Resig
            function makeClassStrict() {
              var isInternal, instance;
              var constructor = function(args) {
                if (this instanceof constructor) {
                  if (typeof this.init == "function") {
                    this.init.apply(this, isInternal ? args : arguments);
                  }
                } else {
                  isInternal = true;
                  instance = new constructor(arguments);
                  isInternal = false;
                  return instance;
                }
              };
              return constructor;
            }
            var MyClass = makeClassStrict();// create "class"
            MyClass.prototype.init = function(employeeName, isWorking) {
              var defaultName = 'notbob';
              this.name = employeeName ? employeeName : defaultName;
              this.working = !!isWorking;
              this.internalValidate = function() {
                return {
                  "check": this.working,
                  "who": this.name
                };
              };
            };
            MyClass.prototype.getName = function() {
              return this.name
            };
            MyClass.prototype.protoValidate = function() {
            return {
                  "check": this.working,
                  "who": this.name
                };
            };
            var instanceBob = MyClass("Bob", true);// create instance
            var instanceFred = MyClass("Fred", false);// create instance
            var mything = instanceFred.internalValidate();// call instance function
            console.log(mything.check + ":" + mything.who);
            var myBobthing = instanceBob.protoValidate();
            console.log(myBobthing.check + ":" + myBobthing.who);
            

            【讨论】:

              【解决方案9】:

              希望你正在寻找这样的东西

              function initValidation()
              {
                  // irrelevant code here
                  this.validate = function(_block){
                      // code here
                  }
              }
              
              var fCall = new initValidation()
              fCall.validate(param);
              

              这会起作用。

              希望这能解决您的问题。

              【讨论】:

                【解决方案10】:

                您可以在initValidation 内拨打validate。像这样。

                function initValidation()
                {
                    // irrelevant code here
                    function validate(_block){
                        // code here
                    }
                
                    return validate(someVar);
                }
                

                validateinitValidation 之外的任何东西都不可见,因为它的scope

                编辑:这是我的解决方案建议。

                (function() {
                    function validate(_block){
                        // code here
                    }
                
                    function initValidation()
                    {
                        // irrelevant code here
                
                        return validate(someVar);
                    }
                
                    function otherFunctions() {
                        // ...
                    }
                
                    // initValidation = function
                }());
                
                // initValidation = undefined
                

                您的所有函数都将对函数包装器之外的任何内容隐藏,但都可以相互看到。

                【讨论】:

                • 如果仍然无法正常工作,请尝试调试 validate。在其中放置一个alert / console.log 调用,看看它是否正在执行。
                • 谢谢。我想从外部initValidation 调用它,但我认为这是不可能的。
                • 不,这就是它嵌套的原因。如果您想在 initValidation 函数之外使用它,请不要嵌套它。
                • 您可以尝试将函数放在initValidation 之外。当然它会是全球性的,但仍然可以从initValidation 访问。为什么不将你所有的函数包装在(function() { /* CODE HERE */ }()) 之类的东西中。它将阻止一切变得全局,但允许您的函数看到彼此。
                • @EduardLuca,如果您想从 outside 其封闭范围访问该函数(在您的问题中,您在里面说,这是完全相反的),您不应该声明它在里面。这是一个设计错误。有很多方法可以解决它,但为什么不直接定义需要调用它的函数呢?
                【解决方案11】:

                应该可以。

                function initValudation() {
                    validate();
                    function validate() {
                
                    }
                }
                

                【讨论】:

                • 不理想 - 因为这里的变量 'validate' 在定义之前就被使用了。
                • @DanielAttfield,在什么基础上不理想?它可能不是你喜欢的风格,但这纯粹是主观的。
                • @davin 我是 Douglas Crockford 的忠实订阅者,我使用 JavaScript 的“好的部分”,并使用样式来使您的代码更好、更易于维护且不易出错。作为基础,我推荐你看这个视频,这是 Crockford 讨论风格的视频,可以比我更好地回答你! youtube.com/watch?v=taaEzHI9xyY&hd=1
                • @DanielAttfield,我的观点是值得指出这是一个风格问题。从语义上讲,它是完全有效的。
                • @davin 我通常不喂巨魔,但我会指出我说的是“不理想”,而不是“错误”。