【问题标题】:Entire JS inside one global variable?整个 JS 在一个全局变量中?
【发布时间】:2018-01-20 23:12:40
【问题描述】:

我的学校任务是创建一个应用程序,其中一个限制是只允许一个名为“App”的全局变量。所以我需要把整个 JS 放在这个变量中。

我想过做这样的事情:

App = function() { this.test = () => alert("test"); }

然后用App.test() 调用它。

但这不起作用,我得到的错误是:

Uncaught TypeError: App.test is not a function at HTMLLIElement.onclick (index.html:25)

我是不是做错了什么?

【问题讨论】:

标签: javascript


【解决方案1】:

为了能够使用包含this.test... 的函数,您需要将其用作“构造函数”,因为函数声明中的this 表示“实例属性”,这意味着您需要显式创建带有new 关键字的App 实例:

    // Declare the global
    var App = function() { this.test = () => alert("test"); }
    
    // Make an instance of an object via the constructor function
    var myApp = new App();
    
    // Invoke the functionality via the instance
    myApp.test()

或者,将App 设置为一个对象,将该对象连接到全局window 对象并将test 设置为App 的属性,所有这些都没有任何实例属性(this 引用),这样可以避免必须创建显式实例:

// Declare the global property as an Object
// and set up a "test" property that stores
// a function in that object:
window.App = { test: function(){alert("test");}}

// Invoke the functionality directly
App.test()

【讨论】:

    【解决方案2】:

    保持您的大部分方法不变,您可以返回一个具有函数作为属性的对象。

    App = function() { 
      return {
        test: () => alert("test"),
        test2: () => alert("test2")
      };
    }
    
    App().test();
    App().test2();

    【讨论】:

      【解决方案3】:

      您需要在变量中将您的应用程序定义为对象,然后您可以使用对象的这些成员,例如:

      // Object creation
      window.App = {};
      

      然后您添加更多属性,如函数或变量,稍后在该变量中使用它。

      window.App.test = function() {
         alert('test');
      }
      
      window.App.variable = 'my variable';
      
      console.log( App.test() );
      console.log( App.variable );
      

      另一件事是您可以从 App 中省略单词 window

      【讨论】:

        【解决方案4】:

        在执行App函数之前没有定义test函数:

        App = () => test = () => alert("test")
        <button onclick='App(); test()'>:</button>

        App 可以定义为对象:

        App = { test: () => alert("test") }
        <button onclick='App.test()'>:</button>

        【讨论】:

          【解决方案5】:

          只是为了借鉴其他答案的建议,当您“命名空间”一些 JS 代码时,这种技术最常用(在浏览器开发中)。命名空间很有用,因为它通过将所有代码添加到window 下的一个命名空间下,帮助开发人员减少全局变量污染。

          这也有助于开发人员模块化代码。

          您可能会不时看到这种模式将代码添加到 window 下的单个命名空间。

          // This first function is what's known as an Immediately-invoked
          // function expression (IIFE). `window` is passed in as an argument
          // to the function - all other declared variables are local to the scope
          // of the function so you don't get anything leaking to global.
          // PS, the semi-colon is there before the opening parenthesis to prevent
          // any errors appearing if you minimise your code
          ;(function (window) {
          
            // Here we declare something new to add to the namespace
            // It could be another object, a string, an array, or a constructor
            // like Model
            function Model() {...}
          
            // If namespace `window.app` doesn't exist instantiate it with
            // an empty object. If it _does_ exist it probably means that another
            // module like this one has already been added to the namespace.
            window.app = window.app || {};
          
            // Then assign your new module as a property under that namespace
            window.app.Model = Model;
          
          })(window);
          

          你以后可以像这样使用它:

          var model = new app.Model();
          var game = new Game(model);
          

          进一步阅读:Addy Osmani on namespacing.

          【讨论】:

            猜你喜欢
            • 2015-11-27
            • 1970-01-01
            • 2017-01-28
            • 1970-01-01
            • 1970-01-01
            • 2021-12-11
            • 2011-05-14
            • 2011-06-22
            相关资源
            最近更新 更多