2016-07-30 10 views
0

Warum passiert Folgendes?Problem beim Zugriff auf den äußeren Funktionsumfang in JS

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()(); 

Ausgang:

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

Fügen Sie einfach '' use strict ";' '' 'f1' hinzu und sehen Sie, was passiert. – ftor

+0

Ich glaube, ich verstehe jetzt, die Benutzung von 'this' innerhalb einer Funktion (nicht ein' Konstruktor' now Objekt 'method') ist das gleiche wie das Definieren einer Variablen ohne' var', was eine schlechte Sache ist, weil dies die Variable macht bezieht sich auf den globalen Bereich, nicht auf den lokalen Bereich der Funktion. –

Antwort

2

Da es hier eigentlich kein Scoping ist. Alle this Zugriffe beziehen sich auf das Objekt window. Wenn Sie also this.myRefVar im inneren Bereich bearbeiten, bearbeiten Sie den Wert tatsächlich unter window.

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

Hier definiert ich einige Variablen und Funktionen. Die Variable theName erklärte zunächst bei root(window) Umfang, dann in myObject Umfang (Es gibt keinen Spielraum wie diese, nur für die Erklärung, und dann in foo Umfang.)

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 

Und hier, ich bin versuchen, über verschiedene Möglichkeiten auf theName Variable zuzugreifen. Wenn es hier tatsächlich 4. Scoping gibt, sollte man nach Funktionsaufruf arbeiten. Die anderen repräsentieren nur die gleiche Idee, aber andere Art und Weise.

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() 

Nach Funktionsaufruf, kann ich noch nicht myObject.theName zugreifen, wie ich gehofft. Das ist, weil, wenn man es so nennt, nicht wirklich Zugriff auf myObject Bereich, anstatt ich versuche, auf theName Eigenschaft der myObject Funktion zugreifen. Und ohne diese Funktion als Objekt zu definieren/instanziieren/zu erstellen, kann ich nicht auf die Eigenschaften zugreifen.

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

Was in Ihrem Code vor sich geht ist eigentlich nicht scopping aber Verschluss. Zum besseren Verständnis:
Scopping
Closures
Similar SO question

+0

Ich mag Ihre Antwort, aber ich konnte nicht alle Beispiele verstehen, die Sie gestellt haben. –

+0

Aha, jetzt klar. –

1

In JavaScript-Funktion haben globale Reichweite Zum Beispiel

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

im obigen Code folgenden wird

self_parent === self_first_child === self_child_of_child 

für mehr wahr sein Info siehe JavaScript-Garden-About-this