Подъем - это действие интерпретатора JavaScript перемещения всех объявлений переменных и функций в верхнюю часть текущей области.
Однако, поднимаются только фактические декларации. оставляя присваивания там, где они есть.
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';
}
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
@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, вы можете извлечь значения.
Если вы измените все свои типы на классы. У вас есть варианты. Большая ошибка перехода от типа к классу заключается в том, что вам нужно использовать новый 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 заставляет переменную имитировать способ работы более тесно.