将变量添加到函数作用域/闭包。函数等价于窗口对象 [英] Add variable to a functions scope / closure. function equivalent of window object

查看:106
本文介绍了将变量添加到函数作用域/闭包。函数等价于窗口对象的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

使用以下代码,我可以从对象中取出值,并将它们添加到全局命名空间。这是在expose函数中定义的

  function expose(key,obj){
window [key] = obj [键];
}



我可以使用它来获取函数,例如下划线的地图

  // before 
map // undefined
_.map //必须使用像这样

expose('map',_)

// after
map // function

我想修改暴露,以便它做同样的工作,但只在一个闭包。如何解决这个问题是我试图表达的。

  map // undefined 

function(){
expose('map',{})

// map可以在这里使用
}())
// map仍然未定义这里。

我知道这个问题在这种情况下可以用 var map = _.map 我在这里介绍一个简化的版本来描述点。我想解决它,如上所述我可以写一个函数,一次暴露多个变量。



对于一个复杂的例子看看这个repo 。



https://github.com/CrowdHailer/cuminjs





//github.com/CrowdHailer/cuminjs/blob/master/spec/cumin_spec.jsrel =nofollow> https://github.com/CrowdHailer/cuminjs/blob/master/spec/cumin_spec.js



大范例来更好地表达我想要的最终结果

  //文件一 - 设置一些核心实用程序
var MyModule =(function(){
var foo = function(){
// ..some functions
};

return {
foo:foo
//加上几个函数
};
}());


//文件二 - 设置一些其他功能。
//使用大量的在文件1中设置的函数
(function(parent){
// var foo = MyModule.foo -trying,避免使用几个也许名称更改

expose([foo,etc],MyModule);

var bar = function(){
// ..其他代码使用foo
};

parent.extend({
bar:bar
});
}(MyModule))


解决方案


我知道这个问题在这种情况下可以解决了 var map = _.map



我想写一个函数,一次暴露多个变量。


你不应该。请查看我对于双重问题的答案是否可以在JavaScript(node.js)中导入变量?

但是, export 变量(不属于你自己的范围)比<$ cc $ c> import ing(到你自己的范围)。基本上,这是不可能的,因为范围(除了全局)不是可以传递的对象,并且可以动态修改。


如何解决此问题


您需要修改函数的代码,想改变/扩展。我可以想出两种方法:




  • 使用 eval export()将返回一个将声明并初始化变量的语句:

      function export(){
    var lines = [];
    for(var p in moduletoexpose)
    lines.push(var+ p += require('moduletoexpose')。+ p +;);
    return lines.join(\\\
    );
    }

    (function(){
    eval(export(...));
    //使用`map`这里
    }类似地,你可以编写一个函数,它接受闭包,反编译它,添加变量声明(例如:


  • <到代码,并使用 Function 构造函数从它创建一个函数。它可能像

      exportTo(...,function(){
    // use`map`here
    //不使用任何自由变量,而是使用全局变量
    })();

    听起来不如 eval 解决方案,但您可能希望查看此答案以了解如何编写此类 exportTo



With the following code I am able to take values out of an object and add them to the global namespace. This is defined in the expose function

function expose(key, obj){
  window[key] = obj[key];
}

I can have been using it to take functions I use a lot out of libraries, such as map from underscore

// before
map               //undefined
_.map             // have to use like this

expose('map', _)

// after
map // function

I would like modify expose so that it does the same job but only in a closure. How to solve this is the question I am trying to articulate.

map //undefined

(function(){
expose('map', {})

// map can be used here 
}())
// map is still undefined here.

I know this problem in this case can be solved with a var map = _.map I am presenting a simplified version to describe the point here. I would like to solve it as described above to I can write a function that exposes more than one variable at a time.

For an complex example have a look at this repo.

https://github.com/CrowdHailer/cuminjs

The tests for the expose function are found here

https://github.com/CrowdHailer/cuminjs/blob/master/spec/cumin_spec.js

Large example to express better what I want the end result to be

// file one - sets up some core utilities
var MyModule = (function(){
var foo = function(){
  // ..some functionality
};

return {
  foo: foo
  // plus several more functions
};
}());


// file two - sets up some other functionality.
// Makes use of lots of the functions set up in file 1
(function(parent){
  // var foo = MyModule.foo -trying to avoid as want to use several maybe names change

  expose([foo, etc], MyModule);

  var bar = function(){
    // .. other code would like to make use of foo
  };

  parent.extend({
    bar: bar
  });
}(MyModule))

解决方案

I know this problem in this case can be solved with a var map = _.map.

That's exactly the (only) way to go.

I want write a function that exposes more than one variable at a time.

You should not. Have a look at my answer on the dual question Is it possible to import variables in JavaScript (node.js)?

However, exporting variables (into a scope that you don't own) is even more complicated than importing (into your own scope). Basically, it is impossible because scopes (apart from global) are not objects that can be passed around, and be dynamically modified.

How to solve this

You need to modify the code of the function whose scope you want to change/extend. I can think of two ways:

  • use eval. export() will return a statement that will declare and initialise the variables:

    function export() {
        var lines = [];
        for (var p in moduletoexpose)
            lines.push("var "+p+" = require('moduletoexpose')."+p+";");
        return lines.join("\n");
    }
    
    (function() {
        eval(export(…));
        // use `map` here
    }())
    

  • Similarly, you could write a function that takes the closure, decompiles it, adds the variable declarations to the code, and uses the Function constructor to create a function from it. It might be used like

    exportTo(…, function() {
        // use `map` here
        // don't use any free variables but global ones
    })();
    

    Doesn't sound as good as the eval solution, but you might want to check out this answer for inspiration on how to write such an exportTo.

这篇关于将变量添加到函数作用域/闭包。函数等价于窗口对象的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆