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";
    }
}

ここでは、いくつかの変数と関数を定義しました。variabletheNameは、最初にスコープで宣言され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さまざまな方法で変数にアクセスしようとしています。ここで実際にスコーピングがある場合、関数呼び出しの後に 4 番目のスコーピングが機能するはずです。他のものは同じアイデアを表しているだけですが、方法は異なります。

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スコープにアクセスしていないためです。そして、実際にこの関数をオブジェクトとして定義/インスタンス化/作成しないと、プロパティにアクセスできません。theNamemyObject

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

あなたのコードで起こっていることは、実際にはスコーピングではなくクロージャーです。理解を深めるために:
Scopping 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 に答える