功能范围和背景的差异

时间:2012-12-22 08:56:01

标签: javascript

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

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

foo();
}
foo(); 

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

2 个答案:

答案 0 :(得分:1)

你会混淆范围和背景。第一个是针对给定函数修复的(除非它由某个函数返回,实际上被注入到外部作用域中),第二个(除其他外,定义了this在此函数中引用的内容)被赋予调用它时的函数 - 实际上可以使用callapply进行更改。

考虑一下:

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

JSFiddle

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

当在构造函数本身(1)中调用方法时,你会得到'从内部调用'记录 - 因为方法的上下文对象(this)现在引用internalObj

当我们将此方法(其引用)分配给另一个局部变量并从那里调用它(2)时,会记录'undefined'。范围显然没有在这里改变,但是上下文变量确实:它现在指的是全局对象。

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

答案 1 :(得分:0)

JavaScript具有功能级别范围。

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

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

  

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

你混淆范围和背景。

范围取决于声明变量的位置(使用var或特殊规则,例如“函数声明的作用域”)。它会影响变量可见的位置。

上下文取决于函数的调用方式。它会影响this的值。

两者没有连接。