另一个变量试图超出函数

时间:2014-07-31 22:07:21

标签: javascript

我在函数内部有一些函数,我在检索变量时遇到问题。在代码中显示我想在testit函数中记录var 3但不确定如何执行此操作会更容易。

test();

function test(){
    var abc;
  function one(){
    abc = 1;
    two();
  }
  var three;
  function two(){
    console.log(abc);
    three = 2;
    testit();
  }
    one();

}

function testit(){
  console.log(three);
  two();
}

5 个答案:

答案 0 :(得分:1)

要对测试对象执行以下操作:

function test(){
    this.abc = 0;
    this.three = 0;
    this.one();
}
test.prototype.one = function(){
    this.abc = 1;
    this.two();
}
test.prototype.two = function(){
    console.log(this.abc);
    this.three = 2;
}
test.prototype.testit = function(){
    console.log(this.three);
    this.two();
}

然后像这样运行:

testObj = new test();
testObj.testit();

希望这会有所帮助。

编辑:顺便说一下:如果你把函数'two'中的一个调用回到函数'testit',你最终会得到一个无限循环。

答案 1 :(得分:1)

以下是对正在发生的事情的解释:

当您在函数中包装代码时,您将获得所谓的function scope。这意味着函数中的作用域属于函数,而不属于其上方或外部的范围(无论您希望以何种方式查看它)。

closure允许表达式(通常是一个函数,如MDN状态)拥有它自己的范围,而共享它的外部或更高范围的范围。

那么,让我们看一个例子:

// This represents the global, or window, scope.
// Analogous to window.outer_var.
var outer_var = 'outer var';

function outer_func() {
    // New scope! Local only to outer_func and those
    // expressions (functions) *enclosed* by 
    // `outer_func(){...}, e.g. inner_func(){...}.
    var inner_var = 'inner var';

    // Only outer_func() or inner-enclosed (to
    // inner_func()'s definition) functions can
    // access inner_func().
    function inner_func() {
        // Another new scope! Can access inner_var
        // and inner_func_var (below). outer_func()
        // canNOT access inner_func_var, though.
        var inner_func_var = 'inner func var';
    }
}

outer_func(); // Of course, it's in scope and accessible.
inner_func(); // This will cause ReferenceError: inner_func is not defined error.

就像它一样(没有包装上下文,带有闭包),var outer_var是使用全局窗口范围创建的。可以通过以下所有方式访问它:

  1. console(window.outer_var);
  2. function outer_func() {console.log(outer_var);}
  3. function inner_func() {console.log(outer_var);}无论inner_func定义在哪里。
  4. 这里,#2/3类似于:

    1. function outer_func() {console.log(window.outer_var);}
    2. function inner_func() {console.log(window.outer_var);}
    3. 全球 this

      1. function outer_func() {console.log(this.outer_var);}
      2. function inner_func() {console.log(this.outer_var);}
      3. 现在,可以通过以下方式访问inner_var

        1. function outer_func() {console.log(inner_var);}
        2. function inner_func() {console.log(outer_var);}仅限于outer_func()
        3. inner_func()也可能只能在outer_func()内访问,因为它属于outer_func()范围,因此在outer_func() *之外不可见/可访问。

          最后,inner_func_var只能通过以下方式访问:

          1. function inner_func() {console.log(inner_func_var);}仅限于outer_func()
          2. 要访问three变量,您有三种选择:

            1. 使three全局可访问(通常不鼓励全局变量,因为当其他代码被其他代码覆盖时,它们很容易引入难以解决的错误。)
            2. three功能返回test()。在这种情况下,访问该值,而不是函数中的实际变量。
            3. 在@ logic8演示时创建一个属性,因此可以将其作为对象的属性进行访问。

            4. *这不完全正确。 outer_func()可以使用return inner_func;将对该函数的引用导出范围。然而,这是一个更高级的概念,这里不会深入讨论。 Here is an example.

答案 2 :(得分:0)

你必须把它放在全球范围内才能这样做:

test();
var three = false;

function test(){
[..]
}

function testit(){
  console.log(three);
  two();
}

答案 3 :(得分:0)

当您使用var声明变量时,它变为该范围的本地变量。如果你想在两个函数中访问three,你可以在没有var的情况下声明它(使它成为全局 - 通常由于充分的理由而不赞成)或者在两个函数之外声明它:var three;

答案 4 :(得分:0)

正确的方法是使用closure pattern in javascript。这会将您的javascript类包装在自己的函数中,因此您在该文件中声明的任何内容都只是代码本地的。

使用jQuery,这很容易实现:

(function($){
  //your code goes here
})(jQuery);

人们通常这样做,所以他们的javascript只在页面准备就绪时执行:

$(document).ready(function(){
    //your code goes here
});

如果你想在文档准备就绪时执行你的代码,那么没有jQuery会有点复杂:

document.addEventListener('DOMContentLoaded', function(){
   console.log('document is ready. I can sleep now'); 
 });

使用您的代码,它看起来像这样:

$(document).ready(function(){
    var test = function(){
        //test code here
    };

    var one = function(){
        //one code here
    };

    var two = function(){
        //two code here
    };

    var three = function(){
        //three code here
    };

    var testIt = function(){
        //test code here
    };
});

这样,您可以安全地访问其他功能,而不会污染全局命名空间。