views:

42

answers:

3

I'm wondering about JScript.NET private variables. Please take a look on the following code:

import System;
import System.Windows.Forms;
import System.Drawing;

var jsPDF = function(){
 var state = 0;

 var beginPage = function(){
  state = 2;
  out('beginPage');
 }

 var out = function(text){
  if(state == 2){   
   var st = 3;
  }
  MessageBox.Show(text + ' ' + state);
 }

 var addHeader = function(){
  out('header');
 }  

 return {
  endDocument: function(){
   state = 1;
   addHeader();
   out('endDocument');
  },

  beginDocument: function(){
   beginPage();
  }
 }
}

var j = new jsPDF();

j.beginDocument();
j.endDocument();

Output:

beginPage 2
header 2
endDocument 2

if I run the same script in any browser, the output is:

beginPage 2
header 1
endDocument 1

Why it is so??

Thanks, Paul.

A: 

Just a guess, but it appears that JScript.NET doesn't support closures the same way as EMCAScript, so the state variable in endDocument() isn't referencing the private member of the outer function, but rather an local variable (undeclared). Odd.

richardtallent
No, they believe they support closures - http://blogs.msdn.com/jscript/archive/2007/07/26/scope-chain-of-jscript-functions.aspx
Paul Podlipensky
A: 

You don't have to use new when calling jsPDF here since you're using a singleton pattern. jsPDF is returning an object literal so even without new you'll have access to the beginPage and endDocument methods. To be perfectly honest I don't know what the specifications call for when using new on a function that returns an object literal so I'm not sure if JScript.NET is getting it wrong or the browser. But for now try either getting rid of the new before jsPDF() or change your function to this:

var jsPDF = function(){
 var state = 0;

 var beginPage = function(){
  state = 2;
  out('beginPage');
 };

 var out = function(text){
  if(state == 2){   
   var st = 3;
  }
  MessageBox.Show(text + ' ' + state);
 };

 var addHeader = function(){
  out('header');
 };

 this.endDocument = function(){
  state = 1;
  addHeader();
  out('endDocument');
 };

 this.beginDocument: function(){
  beginPage();
 };
}

That will allow you to use the new keyword and create more than one jsPDF object.

Bob
A: 

I've come across the same problem. In the following code, the closure bound to fun should contain only one variable called result. As the code stands, the variable result in the function with one parameter seems to be different to the result variable in the closure.

If in this function the line

   result = [];

is removed, then the result in the line

  return result;

refers to the result in the closure.

  var fun = function() {
    var result = [];
    // recursive descent, collects property names of obj
    // dummy parameter does nothing
    var funAux = function(obj, pathToObj, dummy) { 
      if (typeof obj === "object") {
        for (var propName in obj) {
          if (obj.hasOwnProperty(propName)) {
            funAux(obj[propName], pathToObj.concat(propName), dummy); 
          }
        }
      }
      else {
        // at leaf property, save path to leaf
        result.push(pathToObj);
      }
    }
    return function(obj) {
      // remove line below and `result' 3 lines below is `result' in closure
      result = []; // does not appear to be bound to `result' above
      funAux(obj, [], "dummy"); 
      return result; // if result 2 lines above is set, result is closure is a different variable
    };
  }();
Leonardo