2016-07-26 14 views
0

(Ich habe die Fragen viermal geändert, die geänderten Teile in custLog sind mit der entsprechenden Änderungsnummer auskommentiert. Das letzte custLog() steht oben, das vorherige Versionen - am Ende dieser Beschreibung.)Loggin Funktionsumfang, und dies. TypeError: custLog (...). Bind ist keine Funktion

Ich versuche den Wert this in Fenster, innere und äußere Funktionen zu drucken.

<script type="text/javascript"> 

    //HELPING function 
     function whatTypeFnc(obj) { 
      // Angus Croll https://javascriptweblog.wordpress.com/2011/08/08/fixing-the-javascript-typeof-operator/ 
      return ({}).toString.call(obj).match(/\s([a-zA-Z]+)/)[1].toLowerCase(); //array, object, function 
     };  

    //The last changes, the custLog up to date. 
//CustLog is helping function to log if the variables in array names are in the scope of the calling function, and to log their values. 
    var custLog = function (num) { 
      var nameF = this; 
      var names = ['outerVal', 'later', 'innerVal' , 'innerF', 'paramVal', 'tooLate', 'outerF']; 
      var ans = num + ' ' + nameF + " : "; //nameF = : , 
      if (this) { names.forEach(function(item, index, array) { 
        try { 
         var nameVar = eval(item); 
         if(eval(nameVar)) { 
          if (whatTypeFnc(nameVar) !== 'function') { 
           ans+= item + ' = ' + nameVar + ', '; 
          } else { ans+= item + ' = function, '; } } } 
        catch (e) { ans+= item + ' = und, '; } 
      }); } 
      console.log(ans); 
      return ans; 
    }; 

    // the code where i use custLog() to log information about the application specific scope of inner, outer functions and window. 

    var outerVal = 'outerVal'; 
    var later; 
    var that = this; //refers to window 

    function outerF() { 
     var that = this; 
     //custLog('43').bind(this); //gives the same error: TypeError: custLog(...).bind is not a function. 
     custLog('43').bind(that); 
     var innerVal = 'innerVal'; 

     function innerF(paramVal) {  
      var that = this; 
      console.log('innerF this='+this); 
      custLog('47').bind(that); 
      assert(outerVal, "Inner can see the outerVal."); 
      assert(innerVal, "Inner can see the innerVal."); 
      assert(paramVal, "Inner can see the later_second."); 
      assert(tooLate, "Inner can see the tooLate,");    
     } 
     custLog('53').bind(that); 
     later = innerF; 
    }; 

custLog('56').bind(that); //gives the error that custLog('56').bind is not a function 
assert(!tooLate,"Outer can't see the tooLate");     
var tooLate = 'tooLate'; 
custLog('59').bind(that); 
outerF(); 
custLog('61').bind(that); 
later('later_second'); 
custLog('63').bind(that); 

I am getting the TypeError: `custLog(...).bind is not a function`. Custlog is the following: 
56 [object Window] : outerVal = outerVal, innerVal = und, innerF = und, paramVal = und, outerF = function, 
TypeError: custLog(...).bind is not a function 
error source line: custLog('56').bind(that); 

// ***************************************** ****** Der vorherige Code der Frage. Das Problem war, dass sich this nicht auf die Funktionsvariablen bezogen hat. Es wurde durch Kommentare unten beantwortet, aber jetzt ist anderer Fehler entstanden.

I try to print value of `this` in window, inner and outer functions. My logs does not coincide with assert log. Why? 
On line 47 `this` refers to `window` instead of `innerF`, one lines 43 and 53 - to `window` instead of `outerF`. Why? 
Why i do not got logged `innerF` on line 47? 


     // Helping function for assertion and type checking are the same . 
    function assert(value, desc) { .. }; 
    functio whatTypeFnc(obj) { ... }; 

    var outerVal = 'outerVal'; 
    var later; 
    var that = this; //refers to window 

    function outerF() { 
     var that = this; 
     console.log('innerF this='+this); 
     //custLog('43').bind(this); //gives the same error: TypeError: custLog(...).bind is not a function. 
     custLog('43').bind(that); 
     var innerVal = 'innerVal'; 

     function innerF(paramVal) {  
      var that = this; 
      console.log('innerF this='+this); 
      custLog('47').bind(that); 
      assert(outerVal, "Inner can see the outerVal."); 
      assert(innerVal, "Inner can see the innerVal."); 
      assert(paramVal, "Inner can see the later_second."); 
      assert(tooLate, "Inner can see the tooLate,");    
     } 
     custLog('53').bind(that); 
     later = innerF; 
    }; 

    custLog(that, '56'); 
    assert(!tooLate,"Outer can't see the tooLate");     
    var tooLate = 'tooLate'; 
    custLog(that, '59'); 
    outerF(); 
    custLog(that, '61'); 
    later('later_second'); 
    custLog(that, '63'); 

//The previous question custLog 
var custLog = function (ArrObj, num) { 
      var nameF = this; 
      if (ArrObj) { nameF = ArrObj.toString(); } //does not work 
      else { nameF=ArrObj; } 
      var names = ['outerVal', 'later', 'innerVal' , 'innerF', 'paramVal', 'tooLate', 'outerF']; 
      var ans = num + ' ' + nameF + " : "; //nameF = : , 
     if (ArrObj) { names.forEach(function(item, index, array) { 
       try { var nameVar = eval(item); 
        if(eval(nameVar)) { 
         if (whatTypeFnc(nameVar) !== 'function') { 
          ans+= item + ' = ' + nameVar + ', '; 
         } else { ans+= item + ' = function, '; } } } 
       catch (e) { ans+= item + ' = und, '; } 
      }); } 
       /* var descr = Object.getOwnPropertyDescriptor(ArrObj, item); 
       if(descr) { 
        if(ArrObj.hasOwnProperty(item)) { 
         if (whatTypeFnc(ArrObj[item]) !== 'function') { 
          ans+= item + ' = ' + descr.value + ', '; 
         } else { ans+= item + ' = function, '; } } } */ 
      console.log(ans); 
      return ans; 
    }; 

// Helping function for assertion. 
    //From Secrets of JavaScript Ninja by John Resig, Bear Bibeault 
function assert(value, desc) { 
    var resultsList = document.getElementById("results"); 
    if (!resultsList) { 
    resultsList = document.createElement('ul'); 
    document.getElementsByTagName('body')[0].appendChild(resultsList); 
    resultsList.setAttribute('id','results'); 
    } 
    var li = document.createElement("li"); 
    li.className = value ? "pass" : "fail"; 
    li.appendChild(document.createTextNode(desc)); 
    resultsList.appendChild(li); 
} 


The assert results are : 

    Outer can't see the tooLate 
    Inner can see the outerVal. 
    Inner can see the innerVal. 
    Inner can see the later_second. 
    Inner can see the tooLate, 

The log results are : 

    56 [object Window] : outerVal = outerVal, later = undefined, tooLate = undefined, outerF = function, 
    59 [object Window] : outerVal = outerVal, later = undefined, tooLate = tooLate, outerF = function, 
    43 [object Window] : outerVal = outerVal, later = undefined, tooLate = tooLate, outerF = function, 
    53 [object Window] : outerVal = outerVal, later = undefined, tooLate = tooLate, outerF = function, 
    61 [object Window] : outerVal = outerVal, later = function, tooLate = tooLate, outerF = function, 
    47 [object Window] : outerVal = outerVal, later = function, tooLate = tooLate, outerF = function, 
    63 [object Window] : outerVal = outerVal, later = function, tooLate = tooLate, outerF = function, 

Why `this` refer to `[object Window]` instead of `innerF` on line 47, or `outerF` on lines 43 and 53? 

Why on line 47, my log does not see `innverVal=innerVAL` and `paramVal=later_Second`? 
+0

Wenn Sie den Wert von 'this' festlegen müssen, wenn Sie eine Funktion aufrufen, siehe [Function.prototype.call] (https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Funktion/Anruf) und [Function.prototype.apply] (https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/apply) – csum

+0

, die, wo man ist rufen es ab. –

Antwort

1

Ihre erste Frage zu beantworten:

this eigentlich nicht auf eine Funktion überhaupt nicht zurückgreifen. Es hängt mit dem Ausführungskontext einer Funktion zusammen (d. H. Wo eine Funktion aufgerufen wird).

Ihre Funktion custLog ist global definiert. Wenn Sie also innerhalb der verschiedenen Funktionen in Ihrem Code custLog aufrufen, führen Sie tatsächlich einen Verweis auf diese globale Funktion aus und rufen diese Funktion im globalen Gültigkeitsbereich auf. Daher ist der Ausführungskontext für 'custLog', wie Sie ihn in Ihrem Code nennen, das globale Objekt. Alle global definierten Funktionen und Variablen existieren in einem globalen Objekt (das im Browser zufällig das Fensterobjekt ist) und darauf bezieht sich this.

Es gibt Möglichkeiten, in denen können Sie ändern, was this bezieht durch Verfahren wie call, apply und bind, aber ich würde vorschlagen, zumindest durch die MDN Dokumente auf JavaScripts this Schlüsselwort (https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Operators/this)

+0

Ich benutze 'this' nicht in' custLog' Funktion. Ich benutze es in 'innerF' Satz' custLog (this, 'msg') ''; also sollte 'ArrObj' in' custLog' 'diesen' Wert von 'innerF' haben? Ich habe mich geirrt? – olga

+0

Ich habe versucht 'custLog ('num'). Bind (this);' was gab 'TypeError: custLog (...). Bind ist keine Funktion'. – olga

+0

Ich würde empfehlen, diesen Artikel http://www.quirksmode.org/js/this.html zu lesen, um zu verstehen, wie "this" in JavaScript funktioniert. Es kann manchmal schwierig sein, den Umfang von "this" zu erfassen. In Bezug auf die '.bind()' Funktion kann ich nicht sehen, wo Sie es verwenden, aber dieser Artikel ist gut zu lesen auf es https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_objects/Funktion/bind –

0

ich lesen konnte es nicht schaffen, nette custLog (msg) .bind (this) -Funktion zu machen. Beispiele und Vorschläge, wie dies möglich ist, sind willkommen.

Diese Antwort zeigt, wie bestimmte Funktionsumfang zu überprüfen, was mein Ziel war. Ich konnte es nicht schaffen, zu schön custLog (msg) .bind (diese) Funktion zu machen, verwendet thu 5 Zeilen zusammenfassen, wenn i Umfang log:

tableObj[tind]={}; tableObj[tind]['msg']=msg; logs=msg+" : "; 
namesG.forEach(function(item, index, array) { 
    try { eval(item); myCallback(item, index, array, eval(item)); 
    } catch (e) { myCallback(item, index, array, 'er'); }    
}); console.log(logs); tind+=1; 

Trotzdem habe ich kein Beispiel über Online-Anmeldung den Funktionsumfang gefunden. Also vielleicht kann dieser Code für einige Anfänger nützlich sein, die versuchen, den Umfang zu verstehen.

// The idea is that if we have a code as this : 
var Ass_inF; //will be Assigned to inF 
function outF() { 
....var inV1 = Math.random(); 
....function inF(paramVal) { } 
........Ass_inF = inF; 
}//outF 
outF(); 
Ass_inF('final1'); 
outF(); 
Ass_inF('final2'); 

Wir können inV1 Wert in inner Funktion Ass_inF Umfang, trotz der Tatsache, dass outher Funktion outF beendet Ausführung speichern. Auf der anderen Seite sehe ich keine Anwendung von diesem. Warum Wert in einem anderen Funktionsumfang speichern? Wir können es erfolgreich direkt in einer globalen Variable speichern. Wenn wir in der globalen Variablen speichern, wenn wir in irgendeiner Funktion darauf zugreifen können.

<script type="text/javascript"> 

// Vollständige Skript über Umfang

function whatTypeFnc(obj) { 
    // Angus Croll https://javascriptweblog.wordpress.com/2011/08/08/fixing-the-javascript-typeof-operator/ 
    return ({}).toString.call(obj).match(/\s([a-zA-Z]+)/)[1].toLowerCase(); //array, object, function 
};  

//console logs that outV='+eval('outV')=outV, item=outV=outV, itemVal =outV 
//but innerHTML is empty 
function myCallback(item, index, array, itemVal) { 
    //console.log('inside myCallback 0, item='+ item+', itemVal=' + itemVal); 
    if (whatTypeFnc(itemVal) !== 'function') { 
     if(itemVal === 'undefined') { tableObj[tind][item] = '| und'; } 
     else if(itemVal==='') { tableObj[tind][item] = '| empty'; } 
     else if(itemVal===null) { tableObj[tind][item] = '| null'; } 
     else { tableObj[tind][item] = '| '+itemVal; } 
     logs+= item + ' = ' + itemVal + '; '; 
    } else { tableObj[tind][item] = '| fnc' ; logs+= item + ' = function; '; } 
    //console.log('inside myCallback outV='+eval('outV')+' , item='+item+'='+eval(item), ', itemVal ='+itemVal); 
    return logs; 
} 

var logs, msg, table, rowcnt, cellcnt, row, tableObj, tind; 
var namesG = ['outV', 'inV1', 'inV2', 'Ass_inF', 'outF', 'inF', 'paramVal', 'tooLate' ]; 

var outV = 'outV'; 
var Ass_inF, AssP_inF; 
logs = ''; //used for looing scope variables 

tableObj={}; tableObj[0]={}; tableObj[0]['msg'] = 'messages // variables'; 
for (let item of namesG) { tableObj[0][item]=item; } tind=1; 

    msg='67, initial, before outF, global scope '; 
    tableObj[tind]={}; tableObj[tind]['msg']=msg; logs=msg+" : "; 
    namesG.forEach(function(item, index, array) { 
     try { eval(item); myCallback(item, index, array, eval(item)); 
     } catch (e) { myCallback(item, index, array, 'er'); }    
    }); console.log(logs); tind+=1; 

function outF() { 
    var inV1 = Math.random(); 

    /*msg='82, in outF '; tableObj[tind]={}; tableObj[tind]['msg']=msg;logs=msg+" : "; 
    namesG.forEach(function(item, index, array) { 
     try { if (eval(item)) { myCallback(item, index, array, eval(item)); } 
     } catch (e) { myCallback(item, index, array, 'und'); }    
    }); console.log(logs); tind+=1;*/ 

    function inF(paramVal) { 
     var inV2 = 'inV2'; 
     msg='89, in inF(paramVal) '; 
     tableObj[tind]={}; tableObj[tind]['msg']=msg; logs=msg+" : "; 
     namesG.forEach(function(item, index, array) { 
      try { eval(item); myCallback(item, index, array, eval(item)); 
      } catch (e) { myCallback(item, index, array, 'er'); }    
     }); console.log(logs); tind+=1; 

    };//inF 

    Ass_inF = inF; 
    msg='98, in outF, after Ass_inF = inF '; 
    tableObj[tind]={}; tableObj[tind]['msg']=msg; logs=msg+" : "; 
    namesG.forEach(function(item, index, array) { 
     try { eval(item); myCallback(item, index, array, eval(item)); 
     } catch (e) { myCallback(item, index, array, 'er'); }    
    }); console.log(logs); tind+=1; 


    Ass_inF(); 
    msg='106, in outF, after Ass_inF() '; 
    tableObj[tind]={}; tableObj[tind]['msg']=msg; logs=msg+" : "; 
    namesG.forEach(function(item, index, array) { 
     try { eval(item); myCallback(item, index, array, eval(item)); 
     } catch (e) { myCallback(item, index, array, 'er'); }    
    }); console.log(logs); tind+=1; 

    Ass_inF('Ass_1'); 
    msg='113, in outF, after Ass_inF(Ass_1); '; 
    tableObj[tind]={}; tableObj[tind]['msg']=msg; logs=msg+" : "; 
    namesG.forEach(function(item, index, array) { 
     try { eval(item); myCallback(item, index, array, eval(item)); 
     } catch (e) { myCallback(item, index, array, 'er'); }    
    }); console.log(logs); tind+=1; 

}; 

var tooLate = 'tooLate'; 
outF(); 
    msg='124, after outF() '; tableObj[tind]={}; 
    tableObj[tind]['msg']=msg;logs=msg+" : ";  
    tableObj[tind]={}; tableObj[tind]['msg']=msg; logs=msg+" : "; 
    namesG.forEach(function(item, index, array) { 
     try { eval(item); myCallback(item, index, array, eval(item)); 
     } catch (e) { myCallback(item, index, array, 'er'); }    
    }); console.log(logs); tind+=1; 

Ass_inF('final trial 1'); 
    msg='131, final, after Ass_inF(final trial 1) '; 
    tableObj[tind]={}; tableObj[tind]['msg']=msg; logs=msg+" : "; 
    namesG.forEach(function(item, index, array) { 
     try { eval(item); myCallback(item, index, array, eval(item)); 
     } catch (e) { myCallback(item, index, array, 'er'); }    
    }); console.log(logs); tind+=1; 


    outF(); 
    msg='138, after outF() '; tableObj[tind]={}; 
    tableObj[tind]={}; tableObj[tind]['msg']=msg; logs=msg+" : "; 
    namesG.forEach(function(item, index, array) { 
     try { eval(item); myCallback(item, index, array, eval(item)); 
     } catch (e) { myCallback(item, index, array, 'er'); }    
    }); console.log(logs); tind+=1; 

    Ass_inF('final trial 2'); 
    msg='145, final, after Ass_inF(final trial 2) '; 
    tableObj[tind]={}; tableObj[tind]['msg']=msg; logs=msg+" : "; 
    namesG.forEach(function(item, index, array) { 
     try { eval(item); myCallback(item, index, array, eval(item)); 
     } catch (e) { myCallback(item, index, array, 'er'); }    
    }); console.log(logs); tind+=1; 

//Display scope information 
table = document.createElement("TABLE"); 
// table.style="1px solid black"; does not work for cells and rows 
for (let indy in tableObj) { 
    row = table.insertRow(indy); cntx=0;  
    cell = row.insertCell(cntx); cell.innerHTML = indy+' ** '; cntx++; 
    cell = row.insertCell(cntx); cell.innerHTML = tableObj[indy]['msg']; cntx++; 
    cell = row.insertCell(cntx); cell.innerHTML = tableObj[indy]['outV']; cntx++; 
    cell = row.insertCell(cntx); cell.innerHTML = tableObj[indy]['inV1']; cntx++; 
    cell = row.insertCell(cntx); cell.innerHTML = tableObj[indy]['tooLate']; cntx++; 
    cell = row.insertCell(cntx); cell.innerHTML = tableObj[indy]['inV2'];cntx++; 
    cell = row.insertCell(cntx); cell.innerHTML = tableObj[indy]['paramVal']; cntx++; 
    cell = row.insertCell(cntx); cell.innerHTML = tableObj[indy]['Ass_inF']; cntx++; 
    cell = row.insertCell(cntx); cell.innerHTML = tableObj[indy]['outF']; cntx++; 
    cell = row.insertCell(cntx); cell.innerHTML = tableObj[indy]['inF']; cntx++; 
    // ['outV', 'Ass_inF', 'AssP_inF', 'inV1', 'outF', 'inF', 'paramVal', 'tooLate' ]; 
    // for (let indx in tableObj[indy]){ cell = row.insertCell(indx); cell.innerHTML = tableObj[indy][indx]; } 
} 
document.body.appendChild(table); 

    </script> 

Die Beispielausgabe Anmeldung ist wie diese.

0 ** messages // variables outV inV1 tooLate inV2 paramVal Ass_inF outF inF 
1 ** 67, initial, before outF, global scope | outV | er | undefined | er | er | undefined | fnc | er 
2 ** 98, in outF, after Ass_inF = inF | outV | 0.6047199716839021 | tooLate | er | er | fnc | fnc | fnc 
3 ** 89, in inF(paramVal) | outV | 0.6047199716839021 | tooLate | inV2 | undefined | fnc | fnc | fnc 
4 ** 106, in outF, after Ass_inF() | outV | 0.6047199716839021 | tooLate | er | er | fnc | fnc | fnc 
5 ** 89, in inF(paramVal) | outV | 0.6047199716839021 | tooLate | inV2 | Ass_1 | fnc | fnc | fnc 
6 ** 113, in outF, after Ass_inF(Ass_1);  | outV | 0.6047199716839021 | tooLate | er | er | fnc | fnc | fnc 
7 ** 124, after outF() | outV | er | tooLate | er | er | fnc | fnc | er 
8 ** 89, in inF(paramVal) | outV | 0.6047199716839021 | tooLate | inV2 | final trial 1 | fnc | fnc | fnc 
9 ** 131, final, after Ass_inF(final trial 1) | outV | er | tooLate | er | er | fnc | fnc | er 
10 ** 98, in outF, after Ass_inF = inF | outV | 0.5665007054858299 | tooLate | er | er | fnc | fnc | fnc 
11 ** 89, in inF(paramVal) | outV | 0.5665007054858299 | tooLate | inV2 | undefined | fnc | fnc | fnc 
12 ** 106, in outF, after Ass_inF() | outV | 0.5665007054858299 | tooLate | er | er | fnc | fnc | fnc 
13 ** 89, in inF(paramVal) | outV | 0.5665007054858299 | tooLate | inV2 | Ass_1 | fnc | fnc | fnc 
14 ** 113, in outF, after Ass_inF(Ass_1);  | outV | 0.5665007054858299 | tooLate | er | er | fnc | fnc | fnc 
15 ** 138, after outF() | outV | er | tooLate | er | er | fnc | fnc | er 
16 ** 89, in inF(paramVal) | outV | 0.5665007054858299 | tooLate | inV2 | final trial 2 | fnc | fnc | fnc 
17 ** 145, final, after Ass_inF(final trial 2) | outV | er | tooLate | er | er | fnc | fnc | er