写一个库,有什么结构?

Dav*_*mes 24 javascript

我正在写一个图书馆.现在,我将所有内容都写在一个.js文件中,如下所示:

function doThis() {}
var thisVar = 5;
Run Code Online (Sandbox Code Playgroud)

我不确定这是不对的,所以我考虑过:

function Lib() {
  this.doThis = function() {}
  this.thisVar = 5;
}

var lib = new Lib();
Run Code Online (Sandbox Code Playgroud)

然后,在主程序文件上,我将不得不用"lib."调用所有内容,例如"lib.thisVar"或"lib.doThis();".

任何想法哪个更好,或者它们都可以接受?先感谢您.

hon*_*ovk 24

为了避免混乱全局命名空间,我使用这样的结构:

var MyLib = {
    vars: {
        var1: 'value1',
        var2: 'value2'
    },
    func1: function () {
        return this.vars.var1;
    },
    func2: function () {
        alert("This is func2");
    }
};

MyLib.func1();
MyLib.func2();
Run Code Online (Sandbox Code Playgroud)

您会注意到我将所有变量放入它们自己的子对象中,这纯粹是为了便于阅读和开发.


编辑1:

这是我使用的另一种方法

var MyLib = (function MyLib() {
    var _privateVars = {
        "someVar": "This value made public by `someMethod`",
        "privateVar": "Can't see this value"
    };

    // Return the constructor
    return function MyLibConstructor() {
        var _this = this; // Cache the `this` keyword

        _this.someMethod = function () {
            // Access a private variable
            return _privateVars.someVar;
        };

        _this.someOtherMethod = function () {
            // Some other functionality
        };
    };
}());

var myLib = new MyLib(); // invoke

console.log( myLib.someMethod() );
Run Code Online (Sandbox Code Playgroud)

此结构使用JS Closures和构造函数,因此很容易将私有变量保密.

编辑2:

另外,我还使用了一个不返回构造函数的不同闭包设置(例如var x = new MyLib();).

(function(window) {
    var _private = {},
        methods = {},
        topic, init;

    methods.set = function(value) {
        // Set the property & value
        _private[topic] = value;
        return this;
    };

    // A simple get method
    methods.get = function(callback) {
        var response = null;

        // Return the value of topic (property) in a callback
        if (!!callback && typeof callback === 'function') {
            if (_private.hasOwnProperty(topic)) {
                response = _private[topic];
            }
            callback.call(this, response);
        }
        return this;
    };

    // Init method setting the topic and returning the methods.
    init = function(_topic) {
        topic = _topic;

        return methods;
    };

    // Exposure when being used in an AMD environment, e.g. RequireJS
    if (typeof define === 'function' && define.amd) {
        define(function() {
            return init;
        });
        return;
    }

    // Exposure when being used with NodeJS
    if ('undefined' !== typeof module && module.exports) {
        module.exports = init;
        return;
    }

    // Last-in-the-line exposure to the window, if it exists
    window.myLib = init;

    // This line either passes the `window` as an argument or
    // an empty Object-literal if `window` is not defined.
}(('undefined' !== typeof window) ? window : {}));
Run Code Online (Sandbox Code Playgroud)

并看到它在行动:

myLib('something').set('made public, outside of the closure by the `get` method');

myLib('something').get(function(a){
  console.log(a);
});
Run Code Online (Sandbox Code Playgroud)

还请看一下我曝光的方式myLib,考虑它的运行位置,以及它是如何被包含的.

编辑3(7/2017):

作为一个完整的堆栈(w/Node.js)JavaScript工程师,以及Browserify的出现,我完全建议使用Nodejs样式module模式,使用Gulp或Grunt作为构建系统来编译多文件(解耦,更小)一些代码)到一个库中.

此模型有助于鼓励更具功能性的方法,允许开发人员将库中更常见的功能抽象为单独的文件,从而使开发变得更加容易.

哦,并使用ES6!

// file: src/divideIntByFour.js

const divideIntByFour = (int) => {
    return int / 4;
};

module.exports = divideIntByFour;
Run Code Online (Sandbox Code Playgroud)

......作为一个狡猾的例子


Jim*_*ler 11

查看JavaScript模块模式.

http://www.adequatelygood.com/2010/3/JavaScript-Module-Pattern-In-Depth

你可以考虑使你的库与require.js兼容,这是一个完全做这种事情的框架.

http://requirejs.org


tec*_*bar 8

两者在理论上都是可以接受的.但是两者都存在命名与应用程序中使用的其他部分/库冲突的风险.

在第一种情况下,您冒着为各个函数命名冲突的风险,而在后一种情况下,您冒着为库包装器(Lib)选择的函数命名冲突的风险.

首选方法是将它们包装在一个单独的命名空间中,如本页所示:

http://frugalcoder.us/post/2010/02/11/js-classes.aspx

  • 链接已损坏 (2认同)