【问题标题】:Global functions in javascriptjavascript中的全局函数
【发布时间】:2015-06-13 09:29:16
【问题描述】:

我是 js 新手,并试图了解全局和私有函数。我了解全局变量和局部变量。但是如果我有一个名为test.html 的html 和一个名为test1.jstest2.js 的2 个js 文件。现在我将test1.jstest2.js 包含在test.html 中,并在test1.jstest.html 中调用test2.js 中编写的函数。

我在test2.js中写的函数都是这种形式

function abc(){...}

function pqr(){...} etc.

以上这些函数是全局的吗?如果是,我怎么能不让它们成为全球性的并且仍然可以在test1.jstest.html 中访问它们?

正如我所读的那样,全局函数或全局变量不好对吧?

【问题讨论】:

  • 范围与它们位于不同的 JavaScript 文件这一事实无关。运行一个简单的测试。将一个函数放入 test1 并从 test2 调用它。有用吗?
  • 与全局变量几乎完全相同。如果您在“顶层”有一个 var 声明,那么该变量将是全局对象的属性 - 与您使用 function 关键字定义的函数相同。
  • 你到底是什么意思?
  • 您可以将命名空间添加到 window 并将每个文件添加到该命名空间。这样可以防止您用很多变量污染window,我认为这正是您所担心的。
  • 正确。但是该命名空间将被添加到窗口对象中,从技术上讲,我编写的函数仍然是全局的,对吗?但只是它们在一个命名空间下。对吗?

标签: javascript function global


【解决方案1】:

JS 中的所有内容都绑定到包含范围。因此,如果您直接在文件中定义function,它将绑定到window 对象,即它将是全局的。

要使其“私有”,您必须创建一个包含这些功能的对象。你是正确的,乱扔全局范围是不好的,但是你必须在全局范围内放置一些东西才能访问它,JS库也这样做,并且没有其他解决方法。但是考虑一下您在全局范围内放置的内容,单个对象对于您的“库”应该绰绰有余。

例子:

MyObject = {
    abc: function(...) {...},
    pqr: function(...) {...}
    // other functions...
}

为某个地方调用abc,无论是同一个文件还是另一个文件:

MyObject.abc(...);

【讨论】:

  • 您也可以使用 var 将函数设为私有:var mySuperAwesomeFunction = function() {};
  • 是的,但如果你不在 abc 前面写 var,那么 abc 仍然是全局的,并且可以从其他文件作为 abc() 访问。正确的?那有什么意义呢?
  • @Jordumus 这根本不正确。打开JS控制台,写var x = function() {console.log('x')},然后尝试调用window.x()。在浏览器中,window 是全局作用域,因此函数是全局的。
  • @ugandajs 正如@Jordumus 所说,它仅在MyObject 范围内可用,请注意它是abc: function...不是 abc = function...。对于后一种情况,您是正确的,但是对象中不允许使用该表达式,它会引发运行时错误。
【解决方案2】:

在没有任何包装的文件中定义的任何内容都将绑定到窗口对象。任何绑定到 window 对象的东西都是全局的。

例子:

//these are global variables
foo = 123;
var ABC = 'school';

//these are "private" variables
test = function(){
  var foo = 123
}

(function(){
  var ABC = 'school';
}).call(this);

由于每个文件中的全局变量都是window 对象的一部分,因此您可以在文件之间访问它们。创建“私有”变量时添加var 很重要。这表示覆盖当前“包装器”中的任何全局变量。如果我有一个全局变量 foo 并且我在带有 var 的函数中再次定义它,它们将是分开的。

var foo = 123;
(function(){
  var foo = 987; //this foo is separate from the above foo
}).call(this);

如果你有一个“包装器”并且你想定义一个全局函数,你可以这样做:

window.foo = 123;
(function(){
  window.foo = 123;
}).call(this);

这两个函数会做同样的事情。

就个人而言,我更喜欢将所有内容都放在一个包装器中,并且只在需要时使用window 定义全局变量。

(function(){

  //all code goes here

  //define global variable
  window.foo = 123;

})call(this);

【讨论】:

  • 示例中不需要.call,后面的()就足够了(即(function(){...}())
  • 我知道。我是一名咖啡脚本开发人员,我习惯于这样看待它。
  • 如您所说,如果“两个函数都做同样的事情”,那么将全局变量放入“包装器”有什么好处...
【解决方案3】:

如果你不明白为什么全局变量不好,那你为什么要避免它们呢?

全局函数不一定不好。不好的是状态任何人和任何事情都会发生变化。

一般来说,由于您是 Javascript 新手,最好从分布在多个 javascript 文件中的全局函数开始,这些文件通过脚本标签包含在 html 文件中。

当您从初学者过渡到中级时,您将不得不研究一些“模块”解决方案(我个人推荐RequireJS)。

不过现在,您可以使用更简单的模块模式:

var T1 = function() {
   return < some module object >
})(); // notice the parenthesis

谷歌“Javascript 模块模式”。

另见this answer

【讨论】:

    【解决方案4】:
    var SomeName = function() {
    
        var function1 = function (number) {
            return number+1;
        }
    
        var anotherFunction = function (number) {
            return number+2;
        }
    
        return {
            function1: function (number) {
                return function1(number);
            },
            function2: function (number) {
                return anotherFunction(number);
            }
        }
    }();
    

    打电话

    console.log(SomeName.function1(1)); //logs 2
    
    console.log(SomeName.function2(1)); //logs 3
    

    【讨论】:

    • 您也可以return { function1: function1, function2: anotherFunction } 避免重复参数。
    【解决方案5】:

    在 test2.js 中你可以这样写来使函数全局化

    window.abc = function(){...}
    

    然后在 test1.js 中你可以像这样访问它

    window.parent.abc();
    

    希望对你有帮助

    【讨论】:

      【解决方案6】:

      使用全局数据的现代方法(2020 年)是使用全局对象字面量并在其中定义所有需要的逻辑。

      const Website = {
        foo () {
          console.log('foo')
        },
        
        bar () {
          console.log('bar')
        }
      }
      
      document.addEventListener('DOMContentLoaded', () => {
        Website.foo()
        Website.bar()
      })

      如果您的代码比几行代码更复杂,您需要将代码分成多个文件,然后使用 webpack 将它们合并到一个文件中。

      import Foo from './js/Foo.js'
      import Bar from './js/Bar.js'
      
      // define here another object literal or setup document events.
      // webpack will merge all this together into one file
      &lt;script src="js/webpack-merged.js"&gt;&lt;/script&gt;

      您不想使用 html 导入单个 js 文件的原因是 described here。关键是你的性能会很差,所以你必须捆绑所有的 js。

      【讨论】:

        【解决方案7】:

        vos fonctions ne sont pas global si vous faite l'erreur de les incorporé dans par exemple :

        $( document ).ready(function() {  
        function myglobalfunction() { ... }
        });
        

        vous devez 退休

        $( document ).ready(function() {
        

        如果您错误地将它们嵌入其中,则您的函数不是全局的:

        $(document) .ready (function () {
        function myglobalfunction () {
        ...
        }
        });
        

        你必须删除

        $ (document) .ready (function () {
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2017-01-20
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2023-01-29
          • 1970-01-01
          相关资源
          最近更新 更多