Закрытые переменные JScript.NET - PullRequest
0 голосов
/ 23 января 2010

Я задаюсь вопросом о частных переменных JScript.NET. Пожалуйста, взгляните на следующий код:

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

Выход:

beginPage 2
header 2
endDocument 2

если я запускаю тот же скрипт в любом браузере, вывод будет:

beginPage 2
header 1
endDocument 1

Почему это так ??

Спасибо, Пол.

Ответы [ 3 ]

1 голос
/ 24 января 2010

Просто предположение, но похоже, что JScript.NET не поддерживает замыкания так же, как EMCAScript, поэтому переменная state в endDocument () не ссылается на закрытый член внешней функции, а скорее на локальная переменная (необъявленная). Одд.

0 голосов
/ 13 марта 2010

Я сталкивался с той же проблемой. В следующем коде замыкание, связанное с fun, должно содержать только одну переменную с именем result. Когда код стоит, переменная result в функции с одним параметром, похоже, отличается от переменной результата в замыкании.

Если в этой функции строка

   result = [];

удаляется, затем результат в строке

  return result;

относится к результату в закрытии.

  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
    };
  }();
0 голосов
/ 12 февраля 2010

Вам не нужно использовать new при вызове jsPDF, поскольку вы используете шаблон синглтона. jsPDF возвращает литерал объекта, поэтому даже без нового у вас будет доступ к методам beginPage и endDocument. Честно говоря, я не знаю, для чего нужны спецификации при использовании new для функции, возвращающей литерал объекта, поэтому я не уверен, что JScript.NET ошибается или браузер. Но сейчас попробуйте либо избавиться от нового перед jsPDF (), либо измените свою функцию на такую:

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

Это позволит вам использовать новое ключевое слово и создать более одного объекта jsPDF.

...