javascript匿名函数:这个变量是如何在全局命名空间中公开的



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

更新:如果Ns不是全局的,那么做var 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
    }
})();

NS没有理由是全局的(事实并非如此,在Chrome中测试)。然而,namespace将是,因为链式赋值总是这样做(因此在JS中应该避免,除非赋值给之前声明的变量)。

var NS = namespace = {};

执行为:

namespace = {};
var NS = namespace;

更新

从博客文章来看,将"namespace"声明为global是有意的。

因此,这行的"有用性"主要是声明一个全局名称空间对象(namespace——在我看来,这应该明确地完成,以表明其真正的目的是使其全局化)。

和"同时",创建一个本地的、简短的引用(NS)。除了简短之外,理论上在他的库代码的其余部分中引用这个局部变量,而不是窗口的"全局"属性(namespace实际上是window.namespace),在性能方面也会快一点。

在这种情况下,令人困惑的是,在他的博客中,他将全局namespace对象称为ns(请参阅"For this sample,…"一行)。换句话说,就博客文章而言,这行实际上是:

var NS = ns = {}; // which wouldn't exactly make its intent more clear.

相关内容

最新更新