0

javascript 中的函数是否具有全局和本地范围?请参阅下面的代码

function doSomething()
{
    function foo()
{
    alert(this);
}

foo();
}
foo(); 

这里函数foo()没有被执行。但是函数中的“this”关键字指向全局窗口对象,如果函数doSomething()被执行。这意味着函数foo()在全局范围内执行。既然它是在全局范围内执行的,为什么我们不能直接执行嵌套函数而不先执行doSomething().

4

2 回答 2

1

您混淆了范围和上下文。第一个对于给定函数是固定的(除非它由某个函数返回,有效地被注入到外部作用域中),第二个(其中定义了this在这个函数内部引用的内容)在函数被调用时被赋予- 实际上可以用call和改变apply

考虑一下:

var someObj = function() {
    var internalObj = {
        nam: 'internal',
        doSomething: function() {
            console.log('Called from ' + this.name);
        }
    }
    internalObj.doSomething('Internal');      // 1
    var someFunc = internalObj.doSomething;
    someFunc();                               // 2
    return {
        nam: 'external',
        doSomething: internalObj.doSomething
    }        
}
var x = new someObj();
x.doSomething();                              // 3
setTimeout(x.doSomething, 1000);              // 4
setTimeout(x.doSomething.bind({nam:'a new one'}), 2000); // 5

JSF中。

在这个例子中,我们将方法 'doSomething' 定义为internalObj变量的属性,它是这个构造函数的本地属性——如果你试图在外部访问它someObj,你会得到 ReferenceError。

当在构造函数本身 (1) 中调用方法时,您将记录“从内部调用” - 正如方法的上下文对象 ( this) 现在所指的那样internalObj

当我们将此方法(其引用)分配给另一个局部变量并从那里调用它时(2),“未定义”被记录下来。Scope 在这里显然没有改变,但是上下文变量改变了:它现在引用了全局对象。

然后我们将这个方法作为构造函数的结果返回 - 事情开始变得更加有趣:我们的函数现在在外部范围内可用!但请注意,(3) 和 (4) 中其调用结果之间的差异:前者给了我们external(因为这里的上下文对象是由构造函数创建的),后者再次返回我们,undefined即使语法是一样的。) 发生这种情况是因为发送到超时和事件处理程序的函数“丢失”了它们的上下文,简而言之......除非我们用Function.prototype.bind方法修复它,就像在 (5) 中一样。

于 2012-12-22T08:58:07.110 回答
0

JavaScript 具有函数级范围。

任何函数声明都将自动限定到其最近的包含函数。

函数表达式只返回一个值(即一个函数),因此您可以以您选择的任何方式对它们进行作用域。

这意味着函数 foo() 正在全局范围内执行

您混淆了范围和上下文。

范围由声明变量的位置确定(使用var或特殊规则,如“函数声明有范围”)。它影响变量可见的位置。

上下文由函数的调用方式决定。它影响的价值this是什么。

两者没有联系。

于 2012-12-22T08:58:03.990 回答