代码之家  ›  专栏  ›  技术社区  ›  ADJenks

在范围内获取变量,而不使用闭包/包装函数

  •  0
  • ADJenks  · 技术社区  · 7 年前

    如果我有一个随时间变化的变量,并且我想保留它的一个特定实例,那么我必须将其封装在一个闭包中,如下所示:

    function test(){
    	var x = Math.random();
    	// Is there an alternative to using the following closure:
    	var printnum = (function(num){ 
    		return function(){
    			console.log(num);
    		}
    	})(this.x); // Because I think this is ugly
    	
    	return printnum;
    }
    
    var a = test();
    var b = test();
    
    a(); //number
    a(); //same as above
    b(); //different number
    b(); //same as above

    在PHP中,您将使用 use 像这样:

    $a = rand();
    function () use ($a) {
      echo($a);
    }
    

    我真的很欣赏这一点,因为您可以立即看到正在注入的变量,它不会像js中那样列在最下面: (function(b){})(a); 此外,括号也没有过多。我试着用 .apply() .call() 但它们都执行函数,我只想在特定状态下注入一个变量。

    我想我只是想要一个不存在的语言特性,但请证明我错了。有什么想法吗?

    4 回复  |  直到 6 年前
        1
  •  2
  •   dandavis    7 年前

    一种简单的使用方法。bind()(ES5)删除包装函数并避免关闭:

    function test(){
      return console.log.bind(console, Math.random());
    }
    
        2
  •  1
  •   CRice    7 年前

    你会使用es6吗?如果是这样,箭头函数将给出相同的结果,但更简洁:

    function test(){
    	var x = Math.random();
      
    	var printnum = x => () => console.log(x);
    	return printnum(x);
      
        // OR you can invoke immediately:
        // var printnum = (x => () => console.log(x))(x);
        // return printnum;
    }
    
    var a = test();
    var b = test();
    
    a(); //number
    a(); //same as above
    b(); //different number
    b(); //same as above

    好的,在javascript中,您必须通过 x 以某种方式输入函数,以避免它打印其他内容,如果 x个 的值稍后更改。

        3
  •  1
  •   Scott Marcus    7 年前

    我个人喜欢生活,但“一个人的垃圾…”无论如何,您只需要传递一个数字的副本,这样您就不会陷入闭包变量。

    function test(){
      // Because you are working with a number and JavaScript passes all arguments by value
      // a copy of the number will be passed to helper, allowing helper to "disconnect"
      // from using the number in the parent scope
      return helper(Math.random()); 
      
      function helper(num){
        return function(){ console.log(num); }
      }
    }
    
    var a = test();
    var b = test();
    
    a(); //number
    a(); //same as above
    b(); //different number
    b(); //same as above
        4
  •  1
  •   Barmar    7 年前

    没有必要 printnum 作用只需返回内部匿名函数。

    这本质上与PHP相同,但不需要 use() 声明列出要继承到闭包中的变量(PHP需要这样做,因为默认情况下不允许访问外部变量)。

    function test() {
      var x = Math.random();
      return function() {
        console.log(x);
      }
    }
    
    var a = test();
    var b = test();
    
    a(); //number
    a(); //same as above
    b(); //different number
    b(); //same as above