2017-02-17 65 views
0

我在学习JS,想知道,有没有办法通过不返回foo()返回函数bar()或buz()?例如,如果我想返回函数bar();得到2,我能做到吗?它会像foo()。bar(); ?在JavaScript中嵌套范围调用内部函数

// Nested Scopes 
 
function foo() { // can only access itself 
 
    var a = 1; 
 

 
    function bar() { // access to foo(), not buz() 
 
    var b = 2; 
 

 
    function buz() { // access to bar() and foo() 
 
     var c = 3; 
 

 
     console.log(a, b, c); // 1, 2, 3 
 
    } 
 
    buz(); 
 
    console.log(a, b); // 1, 2 
 
    } 
 
    bar(); 
 
    console.log(a); // 1 
 
} 
 
foo(); // 1

+0

你是什么意思的“没有返回foo()”?你的意思是没有'console.log(a);'执行? – 4castle

+0

我一直试图做@Xufox回答的。 –

回答

0

你可以做到这一点,但它是相当过分复杂。

的基本语法是:

foo().bar().buz(); 

在哪里,无论你现有的后添加另一个(),它会打印出水平。查看代码示例。

// Nested Scopes 
 
function foo() { // can only access itself 
 
    var a = 1; 
 

 
    function bar() { // access to foo(), not buz() 
 
    var b = 2; 
 

 
    function buz() { // access to bar() and foo() 
 
     var c = 3; 
 

 
     return (function() { 
 
     console.log(a, b, c); 
 
     }); 
 
    } 
 

 
    return (function() { 
 
     var tmp = function() { 
 
     console.log(a, b); 
 
     return { 
 
      buz: buz 
 
     }; 
 
     }; 
 
     tmp.buz = buz; 
 
     return tmp; 
 
    })(); 
 
    } 
 

 
    return (function() { 
 
    var tmp = function() { 
 
     console.log(a); 
 
     return { 
 
     bar: bar 
 
     }; 
 
    }; 
 
    tmp.bar = bar; 
 
    return tmp; 
 
    })(); 
 
} 
 

 

 
foo().bar().buz(); // (nothing) 
 
foo().bar()().buz(); // 1, 2 
 
foo()().bar()().buz(); // 1 // 1, 2 
 
foo()().bar().buz()(); // 1 // 1, 2, 3 
 
foo()().bar()().buz()(); // 1 // 1, 2 // 1, 2, 3

这种违法行为的事实,你可以在JavaScript中分配属性任何东西,包括功能。

  • foo是指外foo的功能。
  • foo()是指内tmp具有bar属性,指的是内bar功能的另一功能。
  • foo()()实际上调用内部tmp函数,但仍留给您一个具有bar属性的对象,该属性再次引用内部bar函数。

该方法对bar基本相同。

对于buz,但是,(something).buz()只是一个函数,没有任何额外的属性,并且(something).buz()()不返回任何内容,因为这是最终的级别。

+0

IIFE是否在那里隐藏'tmp'?它看起来有点过分复杂。 – 4castle

+0

@ 4castle基本上可以。也许'tmp'只能是'return'之前的一个普通变量。我不确定会发生什么......这可能可以改善...... – Xufox

0

你这样做更像是设置一个变量。

var foo = {

bar: function() { return 3; } }

console.log(foo.bar());

1

当然。您可以在保存该函数的每个阶段返回一个对象,也可以返回该函数本身。这利用了所谓的closure

function foo() { 
 
    var a = 1; 
 
    
 
    function bar() { 
 
    var b = 2; 
 
    
 
    function buz() { 
 
     var c = 3; 
 
     console.log(a, b, c); 
 
    } 
 
    
 
    console.log(a, b); 
 
    return { buz: buz }; 
 
    } 
 
    
 
    console.log(a); 
 
    return { bar: bar }; 
 
} 
 

 
foo().bar().buz();

+0

但是,如果没有它也运行'foo()'功能,你不能调用bar(),也就是说你不能在不记录“1”的情况下记录“1 2”)。也许让内部函数成为属性会更好:'foo.bar()'... – nnnnnn

+0

@nnnnnn我实际上并没有想到一种不调用'foo'的方法。你如何分配这些属性? – 4castle

+0

我不确定。我最初的想法是“好的,只是将'foo'作为设置的一部分来调用”,但这会在调用任何“客户端”代码之前将东西记录到控制台(或者做一些真实世界的功能)功能。 – nnnnnn