Clear
Public
cPath
m.cPath = Justpath( Sys(16) )
Set Default To ( m.cPath )
Local lnHtTime
m.lnHtTime = Seconds()
*-- ClearScriptV8 初始化
Public oNetClearScriptV8
If Vartype( oNetClearScriptV8 ) != "O" Then
oNetClearScriptV8 = NetClearScriptV8Init()
Endif
*支持 VBScript、JavaScript 和 V8
*--注意不要使用“["|"]"来做字符串定界符
*--在V8引擎上注入_VFP,以便在JS中交互调用VFP函数
*--在未理解之前请不要随意更改DEMO代码V8对于VFP程序员来说一个全新的逻辑,随意更改可能导时运行不会正常。
oNetClearScriptV8.AddHostObject( "_vfp" , _vfp )
*--在NetClearScriptV8给VFP A变量赋值
Text To m.lcSetVar noShow
_vfp.SetVar( "A" , 123456789 )
Endtext
oNetClearScriptV8 .Execute( m.lcSetVar )
?"A变量值:"
?A
*--在NetClearScriptV8调用VFP写的函数传参
Set Safety Off
Text To m.lcVFPscript noShow
Procedure Aa( a as Integer , b as Integer )
Return a+b
Endproc
Endtext
Strtofile( m.lcVFPscript
, "V8test1.prg" )
Text To m.lcDoCmdstr noShow
_vfp.DoCmd( "Execscript( 'set Procedure to V8test1.prg Additive ' + Chr(13) + '?? Aa(1,2)')")
Endtext
?"在NetClearScriptV8调用VFP函数:"
oNetClearScriptV8 .Execute( m.lcDoCmdstr )
*--在NetClearScriptV8 添加C# 的程序集 以便可以动态执行C#代码,以下程序集参考
*程序集参考网址:
*!*
mscorlib.dll
*!*
System.Core.dll
*!*
System.Data.dll
*!*
System.Data.OracleClient.dll
*!*
System.Design.dll
*!*
System.dll
*!*
System.EnterpriseServices.dll
*!*
System.Web.dll
*!*
System.Web.Mobile.dll
*!*
System.Xaml.dll
*!*
System.Xml.dll
*NetNetClearScriptV8参考网址:
*如格式化一个日期
Local lolib
m.lolib = oNetClearScriptV8 .CreateHostTypeCollection( "mscorlib", "System.Core" )
oNetClearScriptV8 .AddHostObject( "lib" , m.lolib )
Text To m.lcVFPscript noshow
birthday = new lib.System.DateTime(2007, 5, 22);
_vfp.SetVar( "birthday", birthday.ToLongDateString() )
endtext
oNetClearScriptV8 .Execute(m.lcVFPscript)
?"运行C#格式化一个日期,birthday:"
??birthday
*--在NetClearScriptV8 求当前时间
Text To m.lcVFPscript noshow
Datetime = lib.System.DateTime.Now;
_vfp.SetVar( "Datetime", Datetime );
endtext
oNetClearScriptV8 .Execute(m.lcVFPscript)
?"在NetClearScriptV8 运行C# 求当前时间,Datetime:"
??Datetime
*--在NetClearScriptV8 定义一个字典,并添加foo , 123
Text To m.lcVFPscript noshow
Dictionary = lib.System.Collections.Generic.Dictionary;
dict = new Dictionary(lib.System.String, lib.System.Int32);
dict.Add('foo', 123);
endtext
?"在NetClearScriptV8 运行C# 定义一个字典,并添加foo,123"
oNetClearScriptV8 .Execute(m.lcVFPscript)
*--在NetClearScriptV8 定义一个字典,查找foo 且返值: 123
Local loHost
m.loHost = oNetClearScriptV8 .CreateHostFunctions()
oNetClearScriptV8 .AddHostObject( "host" , m.loHost )
Text To m.lcVFPscript noshow
intVar = host.newVar(lib.System.Int32);
found = dict.TryGetValue('foo', intVar.out);
_vfp.SetVar( "found"
, found
)
_vfp.SetVar( "intVar" , intVar )
endtext
oNetClearScriptV8 .Execute(m.lcVFPscript)
?"在NetClearScriptV8 定义字典,查找foo 且还回值: 123"
?"found:"
??found
?"intVar:"
??intVar
*--执行一个NetClearScriptV8函数,环境默认是模块化的执行,需要使用ES6模块系统的特性
Text To m.lcVFPscript noshow
function GetValue(a,b,c){ return a+b+c; }
_vfp.SetVar("GetValue" , GetValue(1,2,3) )
Endtext
oNetClearScriptV8 .Execute( m.lcVFPscript )
?"执行一个JS函数GetValue,将执行函数结果输出到VFP变量“GetValue”:"
??_vfp.Eval( "GetValue" )
m.cPath = Addbs( m.cPath )
m.cPath = Strtran( m.cPath , "\" , "/" )
*--载外入JS,执行一个JS函数
Text To m.lcVFPscript Textmerge noshow
import * as Arithmetic
from '<<m.cPath >>JavaScript/StandardModule/Arithmetic/Arithmetic.js';
import * as Arithmetic1
from '<<m.cPath >>JavaScript/StandardModule/Arithmetic/Arithmetic.bogus';
import * as Geometry
from '<<m.cPath >>JavaScript/StandardModule/Geometry/GeometryWithDynamicImport.js';
_vfp.SetVar("Add"
, Arithmetic.Add(123, 456) );
_vfp.SetVar("BogusAdd" , Arithmetic1.BogusAdd(123, 456) );
_vfp.SetVar("Area"
, new Geometry.Square(25).Area);
endtext
oNetClearScriptV8 .EvaluateStandard( m.lcVFPscript )
?"执行JavaScript/StandardModule/Arithmetic/Arithmetic.js"
?"Add:"
??_vfp.Eval("Add")
?"BogusAdd:"
??_vfp.Eval("BogusAdd")
?"Area"
??_vfp.Eval("Area")
*--Set path to 路径方式,也可以是Http,不一定是本地
oNetClearScriptV8 .SearchPath = m.cPath +
[JavaScript/StandardModule/Arithmetic] + [;] + ;
m.cPath +
[JavaScript/StandardModule/Geometry]
Text To m.lcVFPscript Textmerge noshow
import * as Arithmetic
from 'Arithmetic.js';
import * as Arithmetic1
from 'Arithmetic.bogus';
import * as Geometry
from 'GeometryWithDynamicImport.js';
_vfp.SetVar("Add"
, Arithmetic.Add(123, 456) );
_vfp.SetVar("BogusAdd" , Arithmetic1.BogusAdd(123, 456) );
_vfp.SetVar("Area"
, new Geometry.Square(25).Area);
endtext
oNetClearScriptV8 .EvaluateStandard( m.lcVFPscript )
?"执行JavaScript/StandardModule/Arithmetic/Arithmetic.js"
?"Add:"
??_vfp.Eval("Add")
?"BogusAdd:"
??_vfp.Eval("BogusAdd")
?"Area"
??_vfp.Eval("Area")
?Chr(13)
*--执行一个V8函数,在代码处引用外部模块
*ES7 引入了 async/await,这是 JavaScript 异步编程的一个重大改进,
*提供了在不阻塞主线程的情况下使用同步代码实现异步访问资源的能力,并且使得代码逻辑更加清晰。
*V8 引擎版本对 await 的处理不一样
Text To m.lcVFPscript Textmerge noshow
async function async1()
{
//_vfp.DoCmd ("clear")
_vfp.DoCmd ("?'async1 start'");
await async2();
_vfp.DoCmd ("?'async1 end'");
}
async function async2(){
_vfp.DoCmd ("?'async2'");
}
_vfp.DoCmd ("?'script start'");
async1();
new Promise((resolve) => {
_vfp.DoCmd ("?'promise1'" );
resolve()
})
.then(() => {
_vfp.DoCmd ("?'promise2'" );
})
_vfp.DoCmd ("?'script end'");
endtext
oNetClearScriptV8 .EvaluateStandard( m.lcVFPscript )
?Chr(13)
* -- 下面列出了使用 V8 运行时的脚本可用的常用语法功能。
* let和const
* 您可以使用 let 和 const 关键字分别定义块级范围的局部变量和块级范围的常量
Text To m.lcVFPscript Textmerge Noshow
// V8 runtime
let s = "hello";
if ( s === "hello" )
{
let s = "world";
_vfp.DoCmd ("
?'" + s + "' ");// Prints "world"
}
_vfp.DoCmd ("
?'" + s + "' "); // Prints "hello"
Endtext
oNetClearScriptV8.Execute( m.lcVFPscript )
?Chr(13)
* -- 箭头函数
* 箭头函数提供了一种在表达式中定义函数的紧凑方式
Text To m.lcVFPscript Textmerge Noshow
// Rhino runtime
function square(x) {
return x * x;
}
_vfp.DoCmd ("
?'" +square(5) + "' "); // Outputs 25
Endtext
oNetClearScriptV8.Execute( m.lcVFPscript )
?Chr(13)
* -- 以下 V8 示例展示了在 Google 表格中构建菜单项时如何使用对象方法:
Text To m.lcVFPscript Textmerge Noshow
function onOpen() {
var ui = SpreadsheetApp.getUi(); // Or DocumentApp, SlidesApp, or FormApp.
ui.createMenu('Custom Menu')
.addItem('First item', 'menu.item1')
.addSeparator()
.addSubMenu(ui.createMenu('Sub-menu')
.addItem('Second item', 'menu.item2'))
.addToUi();
}
var menu = {
item1: function() {
SpreadsheetApp.getUi().alert('You clicked: First item');
},
item2: function() {
SpreadsheetApp.getUi().alert('You clicked: Second item');
}
}
Endtext
oNetClearScriptV8.Execute( m.lcVFPscript )
?Chr(13)
* -- 类提供了一种利用继承在概念上整理代码的方法。V8 中的类主要是一种基于 JavaScript 原型继承的语法糖。
Text To m.lcVFPscript Textmerge Noshow
// V8 runtime
class Rectangle {
constructor(width, height) { // class constructor
this.width = width;
this.height = height;
}
logToConsole() { // class method
_vfp.DoCmd ("
?'Rectangle(width=" + this.width + ",height=" + this.height + ")'" ); // Outputs 25
console.log(`Rectangle(width=${this.width}, height=${this.height})`);
}
}
const r = new Rectangle(10, 20);
r.logToConsole();
// Outputs Rectangle(width=10, height=20)
Endtext
oNetClearScriptV8.Execute( m.lcVFPscript )
?Chr(13)
* --解构赋值
* --解构赋值表达式是一种快速将数组和对象中的值解压缩到不同的变量的方法。
Text To m.lcVFPscript Textmerge Noshow
// Rhino runtime
var data = {a: 12, b: false, c: 'blue'};
var a = data.a;
var c = data.c;
_vfp.DoCmd ("
?'a=" + a + ",c=" + c + "'
" );// Outputs 12 "blue"
var array = [1, 2, 3];
var x = a[0];
var y = a[1];
var z = a[2];
_vfp.DoCmd ("
?'x=" + x + ",y=" + y + ",z=" + z +"'
" );// Outputs 1 2 3
Endtext
oNetClearScriptV8.Execute( m.lcVFPscript )
?Chr(13)
*-- 模板字面量
*-- 模板字面量是允许嵌入表达式的字符串字面量。这样,您就可以避免使用更复杂的字符串串联语句。
Text To m.lcVFPscript Textmerge Noshow
// Rhino runtime
var first
= "a";
var last
= "b";
var id
= "test";
var name =
'Hi ' + first + ' ' + last + '.';
var url =
'http://localhost:3000/api/messages/'
+ id;
_vfp.DoCmd ("
?'name =" + name + "'" ) ;
_vfp.DoCmd ("
?'url =" + url + "'" ) ;
Endtext
oNetClearScriptV8.Execute( m.lcVFPscript )
?Chr(13)
*-- 默认参数
*-- 借助默认参数,您可以在函数声明中为函数参数指定默认值。这样可以简化函数正文中的代码,因为无需为缺失的参数显式分配默认值。
Text To m.lcVFPscript Textmerge Noshow
// Rhino runtime
function hello(greeting, name) {
greeting = greeting || "hello";
name = name || "world";
_vfp.DoCmd ("
?'" + greeting + " " + name + "!" + "'" ) ;
}
hello();
// Outputs "hello world!"
Endtext
oNetClearScriptV8.Execute( m.lcVFPscript )
?Chr(13)
*-- 多行字符串
*-- 您可以使用与模板字面量相同的语法定义多行字符串。与模板字面量一样,这种语法可让您避免字符串串联并简化字符串定义。
Text To m.lcVFPscript Textmerge Noshow
// Rhino runtime
var multiline = "This string is sort of\n"
+ "like a multi-line string,\n"
+ "but it's not really one.";
_vfp.SetVar( "multiline"
, multiline)
Endtext
oNetClearScriptV8.Execute( m.lcVFPscript )
?multiline
?"耗时:"
?? Seconds() - m.lnHtTime
*-- 释放
NetClearScriptV8Dispose()
*-- 初始化 NetClearScriptV8
*-- 返回值:成功=.T. ;失败= .F.
Function NetClearScriptV8Init()
Local loNetClearScriptV8
m.loNetClearScriptV8 = Createobjects( "NetClearScript.V8" , "NetClearScript.dll" )
If Vartype( m.loNetClearScriptV8 ) == "O" Then
Return m.loNetClearScriptV8
Else
Return null
Endif
Endfunc
*-- 释放
Function NetClearScriptV8Dispose()
oNetClearScriptV8.Dispose()
oNetClearScriptV8 = null
Declare Integer ClrUnload IN clrhost.dll
ClrUnload()
Clear Dlls ClrUnload
Endfunc
*-- 实例化DLL中的COM对象到VFP
*-- 返回值:成功=实例化DLL中的COM对象 ;失败= Null
Function Createobjects( ClassName
As String ;
, cDllFilePath As String )
If !file( "clrhost.dll" ) Then
Messagebox( "缺失发行的库“clrhost.dll”" , 16 , Program() )
Return null
Endif
If !file( m.cDllFilePath ) Then
Messagebox( "缺失发行的库“" + m.cDllFilePath + "”" , 16 , Program() )
Return null
Endif
Declare Integer SetClrVersion
IN clrhost.dll string
Declare Integer ClrCreateInstanceFrom
IN clrhost.dll string, string, string@, integer@
SetClrVersion( "v4.0.30319" ) &&v2.0.50727
Clear Dlls SetClrVersion
Local lcError
;
, lnSize
;
, loOb
;
, lnDispHandle
m.lcError
= Space( 512 )
m.lnSize
= 0
m.lnDispHandle = ClrCreateInstanceFrom( Fullpath( m.cDllFilePath ) ,
ClassName , @lcError , @lnSize )
Clear Dlls ClrCreateInstanceFrom
*ClassName
注意类名大小写敏感
If m.lnDispHandle < 1 Then
m.lcError =
Alltrim( Strconv( Strconv( m.lcError , 5 ) , 6 )
)
m.lcError =
Strtran( m.lcError , Chr( 0 ) , "" )
If Empty( m.lcError
) Then
Aerror( ArrayError )
m.lcError = ArrayError(2)
Endif
Messagebox( "实例化类:" + m.ClassName +"出错!原因:" +
Chr(13) + m.lcError , 16 )
Return null
Else
m.loOb = SYS( 3096, m.lnDispHandle )
*Comprop( m.loOb , "UTF8" , 1 )
SYS( 3097 , m.loOb )
Return m.loOb
Endif
Endfunc