此Javascript代码中的"范围"和"上下文"不同

Jam*_*ght 5 javascript

我在我的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;
}
Run Code Online (Sandbox Code Playgroud)

tre*_*der 19

此代码不必要地混淆.这些话contextscope用来表示错误的东西.首先,让我向每个JavaScript开发人员解释它们应该意味着什么:

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

function F() { this.doSomething('good'); }
Run Code Online (Sandbox Code Playgroud)

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

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

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

F.call(obj1);
F.call(obj2);
Run Code Online (Sandbox Code Playgroud)

出现了许多强大的编程模式.函数绑定(Underscore bind或jQuery proxy)就是一个例子.

另一方面,Scope定义了JavaScript在运行时解析变量的方式.JavaScript中只有两个范围 - 全局和函数范围.此外,它还处理称为"范围链"的东西,使封闭成为可能.


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

handler.method.call(
    handler.scope, this, type, data
)
Run Code Online (Sandbox Code Playgroud)

我不知道this上面的电话是什么.

on方法还接受一个context默认为提供scope的情况context是假的.这context随后被用于过滤功能调用trigger.

context !== handler.context
Run Code Online (Sandbox Code Playgroud)

这允许您通过将处理程序与任意对象(它们已调用context)相关联来对您的处理程序进行分组,然后通过指定它来调用整个组context.

同样,我认为这段代码过于复杂,本来可以用更简单的方式编写.但是,您首先不需要编写自己的事件发射器 - 每个库都准备好供您使用.

  • 现在有一个块范围,ES6中的'let'和'const'.如果我错了,请有人纠正我. (6认同)

小智 5

范围涉及变量的可见性,上下文是指在其中执行功能的对象。

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

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