0

为什么会出现以下情况?

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
4

2 回答 2

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通过不同的方式访问变量。如果这里实际上有范围,第四个应该在函数调用后工作。其他只是代表相同的想法,但方式不同。

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.

您的代码中发生的实际上不是范围,而是关闭。为了更好地理解:
Scoping
Closures
Similar SO question

于 2016-07-30T17:44:48.860 回答
1

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

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

在上面的代码中,以下将是真的

self_parent === self_first_child === self_child_of_child

有关更多信息,请参阅JavaScript-Garden-About-this

于 2016-07-30T17:59:32.903 回答