Vb6 Глубоко подсчитайте количество свойств в объекте UDT [дубликат]

Подъем - это действие интерпретатора JavaScript перемещения всех объявлений переменных и функций в верхнюю часть текущей области.

Однако, поднимаются только фактические декларации. оставляя присваивания там, где они есть.

  • переменная / функция, объявленная внутри страницы, глобальна, может обращаться в любом месте этой страницы.
  • variable / Functions, объявленные внутри функции имеют локальный охват. означает, что они доступны / доступны внутри тела функции (scope), они недоступны вне тела функции.

Переменная

Javascript называется свободно типизированным языком. Это означает, что переменные Javascript могут содержать значение любого Data-Type .

global_Page = 10;                                               var global_Page;      « undefined
    « Integer literal, Number Type.   -------------------       global_Page = 10;     « Number         
global_Page = 'Yash';                 |   Interpreted   |       global_Page = 'Yash'; « String
    « String literal, String Type.    «       AS        «       global_Page = true;   « Boolean 
var global_Page = true;               |                 |       global_Page = function (){          « function
    « Boolean Type                    -------------------                 var local_functionblock;  « undefined
global_Page = function (){                                                local_functionblock = 777;« Number
    var local_functionblock = 777;                              };  
    // Assigning function as a data.
};  

Функция

function Identifier_opt ( FormalParameterList_opt ) { 
      FunctionBody | sequence of statements

      « return;  Default undefined
      « return 'some data';
}
  • Функция

    function Identifier_opt ( FormalParameterList_opt ) { 
          FunctionBody | sequence of statements
    
          « return;  Default undefined
          « return 'some data';
    }
    
    • ], объявленные внутри страницы, поднимаются на верх страницы, имеющей глобальный доступ.
    • Функции
    • , объявленные внутри функционального блока, поднимаются на вершину блока.
    • Возвращаемое по умолчанию значение function is [ undefined ', Значение переменной по умолчанию , также «undefined»
      Scope with respect to function-block global. 
      Scope with respect to page undefined | not available.
      

    Объявление функции

    function globalAccess() {                                  function globalAccess() {      
    }                                  -------------------     }
    globalAccess();                    |                 |     function globalAccess() { « Re-Defined / overridden.
    localAccess();                     «   Hoisted  As   «         function localAccess() {
    function globalAccess() {          |                 |         }
         localAccess();                -------------------         localAccess(); « function accessed with in globalAccess() only.
         function localAccess() {                              }
         }                                                     globalAccess();
    }                                                          localAccess(); « ReferenceError as the function is not defined
    

    Функция Expression

            10;                 « literal
           (10);                « Expression                (10).toString() -> '10'
    var a;                      
        a = 10;                 « Expression var              a.toString()  -> '10'
    (function invoke() {        « Expression Function
     console.log('Self Invoking');                      (function () {
    });                                                               }) () -> 'Self Invoking'
    
    var f; 
        f = function (){        « Expression var Function
        console.log('var Function');                                   f ()  -> 'var Function'
        };
    

    Функция, назначенная переменной Пример:

    (function selfExecuting(){
        console.log('IIFE - Immediately-Invoked Function Expression');
    }());
    
    var anonymous = function (){
        console.log('anonymous function Expression');
    };
    
    var namedExpression = function for_InternalUSE(fact){
        if(fact === 1){
            return 1;
        }
    
        var localExpression = function(){
            console.log('Local to the parent Function Scope');
        };
        globalExpression = function(){ 
            console.log('creates a new global variable, then assigned this function.');
        };
    
        //return; //undefined.
        return fact * for_InternalUSE( fact - 1);   
    };
    
    namedExpression();
    globalExpression();
    

    javascript интерпретируется как

    var anonymous;
    var namedExpression;
    var globalExpression;
    
    anonymous = function (){
        console.log('anonymous function Expression');
    };
    
    namedExpression = function for_InternalUSE(fact){
        var localExpression;
    
        if(fact === 1){
            return 1;
        }
        localExpression = function(){
            console.log('Local to the parent Function Scope');
        };
        globalExpression = function(){ 
            console.log('creates a new global variable, then assigned this function.');
        };
    
        return fact * for_InternalUSE( fact - 1);    // DEFAULT UNDEFINED.
    };
    
    namedExpression(10);
    globalExpression();
    

    Вы можете проверить декларацию функции, тест экспрессии на разных браузерах с помощью jsperf Test Runner


    классов функций конструктора ES5 : объекты функций, созданные с использованием Function.prototype.bind

    JavaScript рассматривает функции как объекты первого класса, поэтому, будучи объектом, вы можете назначить pro

    function Shape(id) { // Function Declaration
        this.id = id;
    };
        // Adding a prototyped method to a function.
        Shape.prototype.getID = function () {
            return this.id;
        };
        Shape.prototype.setID = function ( id ) {
            this.id = id;
        };
    
    var expFn = Shape; // Function Expression
    
    var funObj = new Shape( ); // Function Object
    funObj.hasOwnProperty('prototype'); // false
    funObj.setID( 10 );
    console.log( funObj.getID() ); // 10
    

    ES6 введена функция стрелки: выражение функции стрелки имеет более короткий синтаксис, они лучше всего подходят для функций не-метода, и они не могут использоваться в качестве конструкторов.

    ArrowFunction : ArrowParameters => ConciseBody .

    const fn = (item) => { return item & 1 ? 'Odd' : 'Even'; };
    console.log( fn(2) ); // Even
    console.log( fn(3) ); // Odd
    

18
задан Dan 4 June 2013 в 16:21
поделиться

3 ответа

38
ответ дан 9 revs, 2 users 99% 22 August 2018 в 03:40
поделиться

@Dan,

Похоже, вы пытаетесь использовать RTTI UDT. Я не думаю, что вы действительно можете получить эту информацию, не зная о UDT перед временем выполнения. Чтобы начать работу, попробуйте:

Понимание UDTs Из-за отсутствия возможности отражения. Я бы создал свой собственный RTTI для своих UDT.

Чтобы дать вам базовый уровень. Попробуйте это:

Type test
    RTTI as String
    a as Long
    b as Long 
    c as Long
    d as Integer
end type

Вы можете написать утилиту, которая откроет каждый исходный файл и добавит RTTI с именем типа в UDT. Вероятно, было бы лучше поместить все UDT в общий файл.

RTTI будет примерно таким:

«String: Long: Long: Long: Integer»

Используя память UDT, вы можете извлечь значения.

1
ответ дан Gutzofter 22 August 2018 в 03:40
поделиться
  • 1
    Скрученный, но гениальный (я имею в виду это как комплимент!). Я думаю, что будет нетривиальным доступ к памяти RTTI? Кроме того, он решает только часть проблемы - он также хочет регистрировать имена участников. Я думаю, вы можете хранить их тоже в своем RTTI-члене. Я думаю, вы сказали, что это была базовая линия – MarkJ 14 February 2009 в 23:34

Если вы измените все свои типы на классы. У вас есть варианты. Большая ошибка перехода от типа к классу заключается в том, что вам нужно использовать новый keyworld. Каждый раз, когда объявление переменной типа добавляет новое.

Тогда вы можете использовать ключевое слово варианта или CallByName. VB6 не имеет никакого типа отражения, но вы можете составить список допустимых полей и проверить, присутствуют ли они, например

. Тест класса имеет следующий

Public Key As String
Public Data As String

You может затем выполнить следующее

Private Sub Command1_Click()
    Dim T As New Test 'This is NOT A MISTAKE read on as to why I did this.
    T.Key = "Key"
    T.Data = "One"
    DoTest T
End Sub

Private Sub DoTest(V As Variant)
    On Error Resume Next
    Print V.Key
    Print V.Data
    Print V.DoesNotExist
    If Err.Number = 438 Then Print "Does Not Exist"
    Print CallByName(V, "Key", VbGet)
    Print CallByName(V, "Data", VbGet)
    Print CallByName(V, "DoesNotExist", VbGet)
    If Err.Number = 438 Then Print "Does Not Exist"
End Sub

. Если вы попытаетесь использовать поле, которое не существует, будет поднята ошибка 438. CallByName позволяет использовать строки для вызова поля и методов класса.

Что VB6 делает, когда вы объявляете Dim как New, довольно интересно и значительно минимизирует ошибки в этом преобразовании. Вы видите, что это

Dim T as New Test

не обрабатывается точно так же, как

Dim T as Test
Set T = new Test

Например, это будет работать

Dim T as New Test
T.Key = "A Key"
Set T = Nothing
T.Key = "A New Key"

. Это даст ошибку

Dim T as Test
Set T = New Test
T.Key = "A Key"
Set T = Nothing
T.Key = "A New Key"

Причиной этого является то, что в первом примере флаги VB6 T, так что в любой момент доступа к члену он проверяет, является ли T ничем. Если это так, он автоматически создаст новый экземпляр тестового класса, а затем назначит переменную.

Во втором примере VB не добавляет этого поведения.

В большинстве проектов мы строго следим за тем, чтобы мы пошли Dim T в качестве теста, Set T = New Test. Но в вашем случае, поскольку вы хотите конвертировать типы в классы с наименьшим количеством побочных эффектов, используя Dim T, поскольку новый тест - это путь. Это связано с тем, что Dim как New заставляет переменную имитировать способ работы более тесно.

1
ответ дан RS Conley 22 August 2018 в 03:40
поделиться
  • 1
    Будьте осторожны с «Dim As New». Например, если вы делаете & quot; Dim acct As New BankAccount & quot; а затем позже захотите сделать & quot; If acct Is Nothing & quot; он не будет работать должным образом. VB6 будет автоматически создавать acct, если это ничего, поэтому проверка Nothing будет always возвращать False. Иногда может возникнуть проблема ... – Mike Spross 16 February 2009 в 02:13
  • 2
    ... Однако я согласен с вашей точкой здесь. Для типа, который был преобразован в класс, не будет никаких существующих проверок Nothing для переменных этого типа, поэтому это проблема только в том случае, если такая проверка будет добавлена ​​позже. – Mike Spross 16 February 2009 в 02:15
  • 3
    Я исправил персонал, который не был отформатирован как код, он должен быть более четким – RS Conley 16 February 2009 в 14:03
  • 4
    Вау ... это похоже на книгу. – Keith Adler 16 April 2010 в 23:55
Другие вопросы по тегам:

Похожие вопросы: