如何";从对象中取出变量;在javascript中

如何";从对象中取出变量;在javascript中,javascript,syntax,Javascript,Syntax,我正在寻找将对象内容导入全局范围的内容: var y = {} y.x = 5 //do some magic here console.log(x); //5 我想这样做是为了使我可以制作一个易于使用的模块,具有令人难忘的函数名,而不必担心意外地被其他模块覆盖 考虑这个例子: funModule = {}; funModule.washClothes = function(clothes){...} funModule.walkDog = function(dogName){...}

我正在寻找将对象内容导入全局范围的内容:

var y = {}
y.x = 5

//do some magic here

console.log(x); //5

我想这样做是为了使我可以制作一个易于使用的模块,具有令人难忘的函数名,而不必担心意外地被其他模块覆盖

考虑这个例子:

funModule = {};

funModule.washClothes = function(clothes){...}
funModule.walkDog = function(dogName){...}
//etc

funModule.UNITED_STATES_DEFICIT = ...;
在这里,我创建了一个模块,其中包含一些有用的函数和常量(实现和值被替换为“…”)

我不希望用户每次调用函数或使用常量时都必须键入模块名。这将导致非常混乱的代码:

funModule.walkDog(funModule.UNITED_STATES_DEFICIT);

我可以通过全局定义一切来再次尝试:

washClothes = function(clothes){...}
walkDog = function(dogName){...}
//etc

UNITED_STATES_DEFICIT = ...;
但是,如果另一个模块也定义了通常命名的函数
washworths
,我们就有麻烦了。(在我的实际情况中,通常命名的函数是
run


从技术角度来看,我面临的问题如下:

首先,我想使用简单和难忘的名字,使模块易于学习和有趣的使用

其次,我不希望简单的名称使模块无法与其他模块一起使用。特别是随着它的发展,许多常用的名字将被使用。如果用户能够决定是否直接导入名称,那就太好了

第三,当我输入这个时,我意识到我所描述的东西肯定已经存在,在python中。有关更多详细信息,请参阅

tl;dr如何使用javascript完成类似python的导入?

编辑:

似乎没有一种通用的方法可以做到这一点

  • 使用Windows并不能在所有环境中都起作用(但可以在任何通用浏览器中起作用)
  • 显然,ES6模块不能直接用于web浏览器
这个问题不同于Node.js,因为它与Node.js无关。我一直在寻找一种通用的方法来实现这一点,但这似乎不可能,所以我将把它限制在web浏览器上(即chrome、firefox、safari、opera,也许还有ie)

编辑:

这篇关于范围的一般性文章对于任何有类似问题的人都很有用:你想要什么。 如果将对象定义为es6模块,则可以这样做(使用示例中的名称):

然后,
washtwoots
将在导入它的文件中全局可用,就像您想要的一样

如果您真的想要一个神奇的解决方案,如您文章中的注释中所示,并且不想使用ES6,并且您在浏览器中运行,则可以将其放在窗口对象上:

window.x = 5
这就是你想要的。 如果将对象定义为es6模块,则可以这样做(使用示例中的名称):

然后,
washtwoots
将在导入它的文件中全局可用,就像您想要的一样

如果您真的想要一个神奇的解决方案,如您文章中的注释中所示,并且不想使用ES6,并且您在浏览器中运行,则可以将其放在窗口对象上:

window.x = 5

在JavaScript中,至少在浏览器中,全局变量是
窗口
对象的属性:即
window.x
x
(其中
x
是全局变量)引用相同的值。因此,理论上,您可以使用将对象的属性复制到
窗口
对象,使其成为全局变量。这大致相当于Python中的
globals()


但正如在Python中,
import*
通常是个坏主意一样,这听起来也是个坏主意,但更糟糕的是,因为
window
有很多其他属性,您可能不想破坏它们。

在JavaScript中,至少在浏览器中,全局变量是
window
对象的属性:也就是说,
window.x
x
(其中
x
为全局)引用相同的值。因此,理论上,您可以使用将对象的属性复制到
窗口
对象,使其成为全局变量。这大致相当于Python中的
globals()

 Object.prototype.makeglobal=function(){   
    for(key in this){
      if(window[key]){//replace window if youre not in a browser
      //already exist, error handling
      console.error(key+' already exist in window');
   }else{
      window[key]=this[key];
   }}};
但是,正如在Python中,
import*
通常是个坏主意一样,这听起来也是个坏主意,但更糟糕的是,因为
window
有许多其他属性,您可能不想破坏它们

 Object.prototype.makeglobal=function(){   
    for(key in this){
      if(window[key]){//replace window if youre not in a browser
      //already exist, error handling
      console.error(key+' already exist in window');
   }else{
      window[key]=this[key];
   }}};
这样使用:

funModule.makeglobal();
//now you can
washClothes();
但这是不好的,因为它污染了全局对象

2.用户应创建自己的命名空间:

function(){
 this.washClothes();
//more of his content
}.call(funModule);
3.您还可以添加加载程序:

funModule.load=function(func){
    console.log(func); 
    console.log(this);
    func.call(this,this);
};
现在您可以执行以下操作:

funModule.load(function(fun){
 this.washClothes();
 fun.washClothes();
 });
funModule.washClothes("tshirts").washClothes("trousers").washClothes();
4.如果您担心可读性,可以使用函数链接(?):

现在您可以执行以下操作:

funModule.load(function(fun){
 this.washClothes();
 fun.washClothes();
 });
funModule.washClothes("tshirts").washClothes("trousers").washClothes();
这样使用:

funModule.makeglobal();
//now you can
washClothes();
但这是不好的,因为它污染了全局对象

2.用户应创建自己的命名空间:

function(){
 this.washClothes();
//more of his content
}.call(funModule);
3.您还可以添加加载程序:

funModule.load=function(func){
    console.log(func); 
    console.log(this);
    func.call(this,this);
};
现在您可以执行以下操作:

funModule.load(function(fun){
 this.washClothes();
 fun.washClothes();
 });
funModule.washClothes("tshirts").washClothes("trousers").washClothes();
4.如果您担心可读性,可以使用函数链接(?):

现在您可以执行以下操作:

funModule.load(function(fun){
 this.washClothes();
 fun.washClothes();
 });
funModule.washClothes("tshirts").washClothes("trousers").washClothes();

经过一些额外的研究,我找到了一种方法,在不污染全局名称空间的情况下,允许用户直接访问模块内容

此解决方案允许用户:

  • 编写直接引用模块函数/属性的代码
  • 如果有多个模块以相同的样式编写,请定义优先级
  • 仍按模块名称访问模块的函数/属性*
  • *此功能附带一个陷阱

    这是密码


    模块 在funModule.run的作用域和funModule中动态定义函数的唯一方法(我能找到)是使用Eval。使用call、apply或bind来操纵作用域仍然需要使用
    this
    关键字,而这种不同寻常的风格的全部目的是使客户机代码尽可能简单且不重复

    客户代码1 在客户端代码中,可以直接访问除
    funModule.run
    之外的所有内容。因此,全局名称空间保持干净,但用户的代码不需要不必要的重复

    Cli