【问题标题】:issue when access outer function scope in JS在 JS 中访问外部函数范围时的问题
【发布时间】:2016-07-30 17:30:18
【问题描述】:

为什么会发生以下情况?

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

【问题讨论】:

  • 只需将"use strict"; 添加到f1 看看会发生什么。
  • 我想我现在明白了,在函数内部使用this(不是constructor 现在是对象method)与在不使用var 的情况下定义变量是一样的,这很糟糕事情,因为这使得变量引用全局范围,而不是函数局部范围。

标签: javascript scope executioncontext


【解决方案1】:

因为这里实际上没有范围。所有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 范围,而不是我试图访问myObject 函数的theName 属性。而且,如果没有将这个函数实际定义/实例化/创建为对象,我就无法访问这些属性。

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

您的代码中发生的实际上不是作用域,而是闭包。为了更好地理解:
Scopping
Closures
Similar SO question

【讨论】:

  • 我喜欢你的回答,但是我无法理解你提出的所有例子。
【解决方案2】:

在 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

【讨论】:

    猜你喜欢
    • 2013-03-03
    • 2020-05-31
    • 2016-06-23
    • 1970-01-01
    • 1970-01-01
    • 2016-06-24
    • 1970-01-01
    • 2011-06-01
    • 1970-01-01
    相关资源
    最近更新 更多