JavaScript 匿名函数 : how is this variable exposed in global namespace

标签 javascript jquery

我不明白这个库如何使 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 - 在我看来,这应该明确地完成,以表明其意图确实是使其全局化)。

... 和“同时”,创建对它的本地简短引用 (NS)。除了它很短之外,从理论上讲,在他的库代码的其余部分中引用这个局部变量比 window 的“全局”属性(namespace 确实是 window.namespace).

在这种情况下似乎令人困惑的一点是,在他的博客中,他将全局 namespace 对象称为 ns(请参阅“对于此示例, ...”)。换句话说,就博客文章而言,该行实际上是:

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

关于JavaScript 匿名函数 : how is this variable exposed in global namespace,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9080542/

相关文章:

javascript - 无法在 Ext.draw.Container 构造函数中添加 Sprite

javascript - 如何在 mongoose 中使用 $set 动态更新嵌入式文档

javascript - 从 XML 元素获取文本

javascript - 如何刷新具有相同选择的页面? ( Jade /HTML)

jquery - 如何使用 jQuery 捕获加载页面上的事件? ( on() 不起作用)

javascript - useEffect Hook 依赖项未更新

php - 检查是否启用了 Javascript

javascript - 我的 meteor 项目规模正在失控

jquery - CSS3+jQuery图像变换

javascript - 异步包含的 div 的 jQuery Mobile 样式