在JS中访问外部函数作用域时的问题

时间:2016-07-30 17:30:18

标签: javascript scope executioncontext

为什么会发生以下情况?

function f1() {
    this.myRefVar = 30;
    this.myRefVar2 = 30;
    var parent = this;

    return function() {
        this.myRefVar = 20;
        console.log('parent contains ' + Object.keys(parent).filter(function(k) {
            return k.indexOf('myRefVar') > -1;
        }));
        console.log('parent value of myRefVar: ' + parent.myRefVar);
        console.log('this value of myRefVar: ' + this.myRefVar);
    };
}

f1()();

输出:

parent contains myRefVar,myRefVar2
parent value of myRefVar: 20
this value of myRefVar: 20

2 个答案:

答案 0 :(得分:2)

因为这里实际上没有范围。所有this次访问都是指window个对象。因此,当您在内部范围内编辑this.myRefVar时,您实际上是在window编辑值。

var theName = "SO";
var myObject = function(){
    this.theName = "SO2";
    this.foo = function() {
        this.theName = "SO3";
    }
}
  

在这里,我定义了一些变量和函数。变量theName,首先在root(window)范围内声明,然后在myObject范围内(没有这样的范围,仅用于解释,然后在foo范围内。)

console.log(theName); // SO
console.log(this.theName); // SO
console.log(window.theName); // SO
console.log(myObject.theName); // undefined
console.log(myObject.foo); // undefined
console.log(this.foo); // undefined
console.log(window.foo); // undefined
  

在这里,我试图通过不同的方式访问theName变量。如果实际上有scopping,那么第四个应该在函数调用后工作。其他人只是代表相同的想法,但方式不同。

myObject();

console.log(theName); // SO2
console.log(this.theName); // SO2
console.log(window.theName); // SO2
console.log(myObject.theName); // undefined
console.log(myObject.foo); // undefined
console.log(this.foo); // function myObject/this.foo()
console.log(window.foo); // function myObject/this.foo()
  

在函数调用之后,我仍然无法像我希望的那样访问myObject.theName。这是因为,以这种方式调用它myObject.theName并不实际访问myObject范围,而是我尝试访问theName函数的myObject属性。并且,在没有实际定义/实例化/创建此函数作为对象的情况下,我无法访问属性。

myObject.theName;// undefined. Accessing myObject as a function
new myObject().theName // SO2. Accessing an object derived from myObject.

你的代码中发生的事情实际上并不是关闭而是关闭。为了更好地理解:
Scopping
Closures
Similar SO question

答案 1 :(得分:1)

在JavaScript函数中具有全局范围 例如

thisismydog

在上面的代码中将是真的

function parent() {
  var self_parent = this;
  function firstChild() {
    var self_first_child = this;
    function childOfChild() {
        var self_child_of_child = this;
    }
  }
}

了解更多信息,请参阅JavaScript-Garden-About-this