9

我在我的 Javascript 代码中使用了这个基本的事件系统,并试图为我的同事记录它。我不太确定这段代码中的“范围”和“上下文”有什么区别。谁能帮我理解为什么我什至都需要它们?

this.myClass.prototype.on = function (type, method, scope, context) {
    var listeners, handlers, scope;
    if ( !(listeners = this.listeners) ) {
        listeners = this.listeners = {};
    }

    if ( !(handlers = listeners[type]) ) {
        handlers = listeners[type] = [];
    }

    scope = (scope ? scope : window);
    handlers.push({
        method: method,
        scope: scope,
        context: (context ? context : scope)
    });
}

this.myClass.prototype.trigger = function(type, data, context) {
    var listeners, handlers, i, n, handler, scope;
    if (!(listeners = this.listeners)) {
        return;
    }
    if (!(handlers = listeners[type])){
        return;
    }
    for (i = 0, n = handlers.length; i < n; i++){
        handler = handlers[i];
        if (context && context !== handler.context) continue;
        if (handler.method.call(
            handler.scope, this, type, data
        )===false) {
            return false;
        }
    }
    return true;
}
4

2 回答 2

26

这段代码不必要地令人困惑。context和一词scope用于表示错误的事物。首先,让我解释一下它们对每个 JavaScript 开发人员应该意味着什么:

函数的上下文是该函数的值this——即作为方法调用该函数的对象。

function F() { this.doSomething('good'); }

您可以在不同的上下文中调用此函数,如下所示:

obj1 = { doSomething: function(x) { console.log(x); } }

obj2 = { doSomething: function(x) { alert(x); } }

F.call(obj1);
F.call(obj2);

有许多强大的编程模式由此产生。函数绑定(下划线bind或 jQuery proxy)就是一个例子。

另一方面,范围定义了 JavaScript 在运行时解析变量的方式。JavaScript中只有两个四个作用域——全局作用域、函数作用域、块作用域和模块作用域。此外,它还处理使闭包成为可能的称为“作用域链”的东西。


您的on方法保存变量scope,然后在trigger函数中将其用作上下文,这令人困惑(它不应该被命名scope——它是上下文):

handler.method.call(
    handler.scope, this, type, data
)

而且我不知道this上面的电话是什么。

on方法还接受一个context默认为提供scope的,以防万一context是假的。然后context使用它来过滤要调用的函数trigger

context !== handler.context

这使您可以通过将处理程序与任意对象(它们称为context)关联来对处理程序进行分组,然后只需指定context.

同样,我认为这段代码过于复杂,本可以用更简单的方式编写。但是,你不应该首先像这样编写自己的事件发射器——每个库都准备好供你使用。

于 2013-01-14T17:56:13.420 回答
8

范围与变量的可见性有关,上下文是指在其中执行函数的对象。

作用域:在 JavaScript 中,作用域是通过使用函数来实现的。当您在函数内部使用关键字“var”时,您正在初始化的变量是私有的,并且在该函数之外无法看到。但是,如果这个函数内部有函数,那么那些“内​​部”函数可以“看到”那个变量;该变量被称为“范围内”。函数可以“看到”在它们内部声明的变量。他们还可以“看到”任何在其外部声明的内容,但不能“看到”在嵌套在该函数中的函数内部声明的内容。这是 JavaScript 中的作用域。

上下文:它指的是在其中执行函数的对象。当您使用 JavaScript 关键字“this”时,该词指的是函数正在其中执行的对象。

于 2017-10-30T05:22:59.573 回答