使用模块化模式时,不会调用Javascript函数

时间:2014-08-25 12:30:50

标签: javascript

我正在尝试使用模块化模式编写我的javascript代码,但我在调用内部函数时遇到问题,并且还存在一些安全问题。我可以轻松打开控制台并输入我的命名空间名称。变量并更改变量值。

JS

以下JS代码工作正常,但正如我所说,我可以从控制台更改gridValue。我该如何避免这种情况。我将在我的所有功能中使用此变量。

    var myTicTacToe =  {
        turn:'X',
        score: {
            'X': 0,
            'O': 0
        },
        gridValue: 0,

        fnLoad:function () {
            var select = document.getElementById("grid");
            for (i = 3; i <= 100; i += 1) {
                var option = document.createElement('option');
                select.options[select.options.length] = new Option(i + ' X ' + i, i);
            }
        }
    }

window.onload = function(){
      myTicTacToe.fnLoad();
}

下面一个是在调用fnLoad时给我一个问题。

var myTicTacToe = function(){
    var turn = 'X',
        score =  {
            'X': 0,
            'O': 0
        },
        gridValue =  0,

    fnLoad = function () {
        var select = document.getElementById("grid");
        for (i = 3; i <= 100; i += 1) {
            var option = document.createElement('option');
            select.options[select.options.length] = new Option(i + ' X ' + i, i);
        }
    }
}

    window.onload = function(){
          myTicTacToe.fnLoad();
    }
  1. 如何保护我的gridValue或First模式中的任何变量?
  2. 为什么我不能像第一个一样调用fnLoad?我怎么称呼它?
  3. 这两种模式之间的区别是什么?
  4. 在我使用var声明任何变量的第一个代码中,它给了我错误。为什么会这样?

3 个答案:

答案 0 :(得分:2)

您所指的是 Revealing Module Pattern 。除非您明确退回

,否则一切都是私密的
var myTicTacToe = (function(){
    var turn = 'X',
        score =  {
            'X': 0,
            'O': 0
        },
        gridValue =  0,

    fnLoad = function () {
        var select = document.getElementById("grid");
        for (i = 3; i <= 100; i += 1) {
            var option = document.createElement('option');
            select.options[select.options.length] = new Option(i + ' X ' + i, i);
        }
    };

    return {
        load: fnLoad //fnLoad is now publicly named "load".
    };
})();

window.onload = function(){
      myTicTacToe.load();
}

/* Or even
window.onload = myTicTacToe.load; //Because it's a single function.
*/

至于你的具体问题:

  1. 你不能。默认情况下,所有对象成员都是公共模块模式。
  2. 因为您没有return编辑它,请参阅上面的示例。
  3. 一个允许私人会员,一个不允许。揭示模式允许私人。
  4. 我不明白我们在谈论哪个变量。但如果它是一个对象成员,则不应使用var声明它。

答案 1 :(得分:1)

您可以使用闭包使gridValue成为私有变量。考虑这种模式:

var myTicTacToe =  (function(){
        var turn = 'X'.
            score =  {
                'X': 0,
                'O': 0
            },
            gridValue = 0;

        return {
            fnLoad: function () {
                  var select = document.getElementById("grid");
                  for (i = 3; i <= 100; i += 1) {
                      var option = document.createElement('option');
                      select.options[select.options.length] = new Option(i + ' X ' + i, i);
                  }
             }
        };
    })();

window.onload = function(){
      myTicTacToe.fnLoad();
}

这里我们使用IIFE来关闭局部变量,这样只有fnLoad函数才能访问它们。稍后返回fnLoad函数并调用填充命名空间,以便程序的其他部分可以公开访问它。

这种模式非常有用。在此处阅读更多内容:http://css-tricks.com/how-do-you-structure-javascript-the-module-pattern-edition/

答案 2 :(得分:1)

使用javascript时,此链接是我的常量参考。它在解释使用javascript的不同模式方面做得非常出色,我打赌将有助于解决您的问题。

http://www.addyosmani.com/resources/essentialjsdesignpatterns/book/#designpatternsjavascript

这是您重构的代码,用于保护您的私有变量,并且只允许您声明的方法是公共的。我正在使用下面的“揭示模块化模式”。

var myTicTacToe = (function () {

    // PRIVATE AREA
    var turn = 'X';
    var score = {
        'X': 0,
        'O': 0
    };
    var gridValue = 0;

    function fnLoad() {
        var select = document.getElementById("grid");
        for (i = 3; i <= 100; i += 1) {
            var option = document.createElement('option');
            select.options[select.options.length] = new Option(i + ' X ' + i, i);
        }
    }

    // PUBLIC METHODS
    return {
        Load: fnLoad
    }

})();

然后将其称为

myTicTacToe.Load();

如果您需要传递一个依赖项,例如jQuery或您创建的其他模块,那么您将在(function(HERE))中创建参数,然后在最后一组括号中的底部传递它。是使用jQuery的代码示例。

var myTicTacToe = (function ($) {

    // PRIVATE AREA
    var turn = 'X';
    var score = {
        'X': 0,
        'O': 0
    };
    var gridValue = 0;

    function fnLoad() {
        var select = $('#grid');
        for (i = 3; i <= 100; i += 1) {
            var option = document.createElement('option');
            select.options[select.options.length] = new Option(i + ' X ' + i, i);
        }
    }

    // PUBLIC METHODS
    return {
        Load: fnLoad
    }
})($);