Google 应用程序脚本提供了一个 library feature ,如果您包含项目 key ,则会将库添加为全局对象。我正在寻找迭代添加库的所有功能。这曾经在 rhino 中是可能的带有 for...in
循环的引擎。但我无法遍历 v8 中的库的任何属性引擎。
In the V8 runtime, a project and its libraries are run in different execution contexts and hence have different globals and prototype chains.
谁能解释这个对象是如何创建的或者如何访问它的所有属性?
项目 A:
function testLib(prop = 'main') {
const isEnumerable = MyLibrary.propertyIsEnumerable(prop);
const isOwnProperty = MyLibrary.hasOwnProperty(prop);
console.info({ isEnumerable, isOwnProperty }); // { isEnumerable: false, isOwnProperty: true }
console.info(prop in MyLibrary);//true
for (const property in MyLibrary) {
//loop doesn't start
console.info(property);
}
console.info(Object.getOwnPropertyDescriptor(MyLibrary, prop)); //logs expected data:
/*{ value: [Function: main],
writable: true,
enumerable: false,
configurable: true }*/
console.log(Object.getOwnPropertyDescriptors(MyLibrary)); //actual: {} Expected: array of all functions including `main`
MyLibrary.a = 1;
console.log(Object.getOwnPropertyDescriptors(MyLibrary)); //actual: {a:1} Expected: array of all functions including `main`
}
function testPropDescriptors() {
const obj = { prop1: 1, b: 2 };
console.log(Object.getOwnPropertyDescriptors(obj)); //logs expected data
/*{prop1: { value: 1, writable: true, enumerable: true, configurable: true },
b: { value: 2, writable: true, enumerable: true, configurable: true } }*/
}
我的图书馆(项目 B):
function main(){}
function onEdit(){}
重现,
- 通过 clicking here 创建一个新项目- 比方说,项目 A
- Create a another script project (比如项目 B):
- 在项目B中添加一个名为
main
的函数 - Deploy it单击右上角的部署。
- add it's key在项目 A 中并将其命名为
MyLibrary
。
- 在项目B中添加一个名为
- 将上面的脚本复制粘贴到项目A中,选择
testLib
函数并点击运行
最佳答案
问题和解决方法:
我一直在寻找在启用 V8 的情况下从客户端直接检索库端的属性和函数的方法。但不幸的是,我仍然找不到它。因此,就我而言,我使用了 2 种解决方法。
使用 Apps Script API 和/或 Drive API 检索所有脚本。
将属性和函数包装在一个对象中。
通过上述解决方法,可以从客户端检索库端的属性和函数。
解决方法 1:
在此解决方法中,库端的所有脚本均使用 Apps Script API 和 Drive API 检索。
示例脚本 1:
在此示例中,使用了 Apps Script API。因此,当您使用此脚本时,请将 Google Cloud Platform Project 链接到 Google Apps Script Project。 Ref并且,请在 API 控制台启用 Apps Script API。
const projectIdOflibrary = "###"; // Please set the project ID of the library.
const url = `https://script.googleapis.com/v1/projects/${projectIdOflibrary}/content`;
const res = UrlFetchApp.fetch(url, {headers: {authorization: "Bearer " + ScriptApp.getOAuthToken()}});
const obj = JSON.parse(res.getContentText())
const functions = obj.files.reduce((ar, o) => {
if (o.name != "appsscript") ar.push(o);
return ar;
}, []);
console.log(functions)
// console.log(functions.map(({functionSet}) => functionSet.values)) // When you want to see the function names, you can use this line.
当此脚本用于您的库脚本时,
console.log(functions.flatMap(({functionSet}) => functionSet.values))
返回[ { name : 'main' }, { name: 'onEdit' } ]
.在这种情况下,即使库是 Google Docs 的容器绑定(bind)脚本,该脚本也可以工作。
示例脚本 2:
在此示例中,使用了 Drive API。因此,当您使用此脚本时,请在 Advanced Google 服务中启用 Drive API。
const projectIdOflibrary = "###"; // Please set the project ID of the library.
const url = `https://www.googleapis.com/drive/v3/files/${projectIdOflibrary}/export?mimeType=application%2Fvnd.google-apps.script%2Bjson`;
const res = UrlFetchApp.fetch(url, {headers: {authorization: "Bearer " + ScriptApp.getOAuthToken()}});
const obj = JSON.parse(res.getContentText())
const functions = obj.files.reduce((ar, o) => {
if (o.name != "appsscript") ar.push(o.source);
return ar;
}, []);
console.log(functions)
当此脚本用于您的库脚本时,
console.log(functions)
返回[ 'function main(){}\nfunction onEdit(){}\n ']
.在这种情况下,不会自动解析函数名称。但 Google Apps Script Project 不需要与 Google Cloud Platform Project 关联。但是,当库是 Google Docs 的容器绑定(bind)脚本时,不能使用此脚本。在这种情况下,当库仅为独立类型时,可以使用此脚本。请注意这一点。
解决方法 2:
在此解决方法中,库端的属性和函数用对象包装。
示例脚本:库端
var sample1 = {
method1: function() {},
method2: function() {}
};
var sample2 = class sample2 {
constructor() {
this.sample = "sample";
}
method1() {
return this.sample;
}
}
示例脚本:客户端
function myFunction() {
const res1 = MyLibrary.sample1;
console.log(res1)
const res2 = Object.getOwnPropertyNames(MyLibrary.sample2.prototype);
console.log(res2)
}
- 在这种情况下,
console.log(res1)
和console.log(res2)
返回{ method1: [Function: method1], method2: [函数:method2]
和[ 'constructor', 'method1' ]
,分别为。
引用资料:
关于javascript - 如何遍历 v8 中全局对象(库)的所有属性/函数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/70032506/