javascript匿名函数:如何在全局命名空间中公开此变量

时间:2012-01-31 13:45:50

标签: javascript jquery

我不明白这个库如何使NS var可以在全局命名空间中访问,因为它是用var声明的,你能解释一下吗。

更新:如果Ns不是全局的,那么做NS NS = namespace = {}的目的是什么? ?

http://blog.stephenrushing.com/index.php/javascript/custom-events-in-javascript/

(function () {
    var NS = namespace = {};
    var EVENTS = NS.events = {};
    var eventify = EVENTS.eventify = function (target1, targetN) {
            for (var t = 0; t < arguments.length; t++) {
                var target = arguments[t];
                if (!target.__listeners) {
                    if (!target.events) target.events = {};
                    target.__listeners = {};
                    target.dispatchEvent = function (eventType, eventData) {
                        if (this.events[eventType]) this.events[eventType].dispatch(this, eventData);
                    };
                    target.addEventListener = function (eventType, callback, bubbles) {
                        return new EVENTS.Listener(this, eventType, callback, bubbles);
                    };
                    target.removeEventListener = function (eventType, callback) {
                        var listeners = this.__listeners[eventType];
                        for (var l = 0; listeners && l < listeners.length; l++)
                        if (listeners[l] === callback || listeners[l].callback === callback) listeners.splice(l, 1);
                    };
                }
            }
        }
    var Event = EVENTS.Event = function (type) {
            this.type = type;
            this.history = [];
        }
    Event.prototype = {
        bubbleTo: null,
        currentTarget: null,
        dispatch: function (target, eventData, currentTarget) {
            this.target = target;
            this.currentTarget = currentTarget || target;
            var timeStamp = new Date();
            this.timeStamp = timeStamp;
            this._stopProp = false;
            if (!currentTarget) {
                var histObj = {
                    eventData: eventData,
                    timeStamp: timeStamp
                };
            } else {
                var histObj = currentTarget.events[this.type].history[currentTarget.events[this.type].history.length - 1];
            }
            histObj.target = target;
            histObj.currentTarget = currentTarget || target;
            this.history.push(histObj);
            var listeners = target.__listeners[this.type],
                result;
            for (var l = 0; listeners && l < listeners.length; l++) {
                var listener = listeners[l];
                if (eventData) result = listener.callback.call(target, this, eventData);
                else result = listener.callback.call(target, this);
                if (typeof (result) !== "undefined" && result !== null) this.result = result;
                if (this._stopImmProp) break;
            }
            if (this.bubbleTo !== null && !this._stopProp) this.bubbleTo.events[this.type].dispatch(this.bubbleTo, eventData, this.currentTarget);
        },
        result: true,
        _stopImmProp: false,
        stopImmediatePropagation: function () {
            this._stopImmProp = true
        },
        _stopProp: false,
        stopPropagation: function () {
            this._stopProp = true
        },
        target: null,
        type: null,
        history: null
    }
    var Listener = EVENTS.Listener = function (target, eventType, callback, bubbles) {
            this.target = target;
            this.callback = callback;
            this.bubbles = (bubbles !== null) ? bubbles : true;
            if (!target.events[eventType]) target.events[eventType] = this.event = new EVENTS.Event(eventType);
            this.event = target.events[eventType];
            if (!target.__listeners[eventType]) target.__listeners[eventType] = [];
            target.__listeners[eventType].push(this);
        }
    Listener.prototype = {
        bubbles: true,
        callback: function (evt, data) {},
        remove: function () {
            var idx = Array.indexOf(this.target.__listeners[this.event.type], this);
            this.target.__listeners[this.event.type].splice(idx, 1);
            delete this;
        },
        event: null,
        target: null
    }
})();

1 个答案:

答案 0 :(得分:3)

没有理由NS是全球性的(并且不是,在Chrome中进行测试)。但是,namespace将是,因为链式赋值总是这样做(因此在JS中应该避免,除非分配给先前声明的变量)。

var NS = namespace = {};

执行为:

namespace = {};
var NS = namespace;

<强>更新

从博客文章来看,“名称空间”作为全球声明是有意的。

因此,该行的“有用性”主要是声明一个全局命名空间对象(namespace - 在我看来,应该已经明确地完成,以表明其目的实际上是使其全局化)。

...和“同时”,创建一个本地的简短引用(NS)。除了它很短之外,理论上它在性能方面也要快一点,在其余的库代码中引用这个局部变量,而不是窗口的“全局”属性(namespace真的是{{1} })。

在这种情况下似乎混淆的一点是,在他的博客中,他将全局window.namespace对象称为namespace(参见“对于此示例,......”这一行)。换句话说,就博客文章而言,该行确实是:

ns