[英]How to iterate through all properties/functions of a global object(library) in v8?
Google 應用程序腳本提供了一個庫功能,如果您包含項目密鑰,則會將一個庫添加為全局 object。 我正在尋找迭代添加庫的所有功能。 這曾經在帶有for...in
循環的rhino引擎中是可能的。 但是我無法遍歷v8引擎中庫的任何屬性。
文件說
在 V8 運行時中,項目及其庫在不同的執行上下文中運行,因此具有不同的全局和原型鏈。
誰能解釋這個 object 是如何創建的或如何訪問它的所有屬性?
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`
}
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 } }*/
}
function main(){}
function onEdit(){}
為了重現,
我一直在尋找在啟用 V8 下從客戶端直接檢索庫端的屬性和函數的方法。 但不幸的是,我仍然找不到它。 因此,就我而言,我使用了兩種解決方法。
使用 Apps Script API 和/或 Drive API 檢索所有腳本。
將屬性和函數包裝在 object 中。
通過上述變通方法,可以從客戶端檢索庫端的屬性和函數。
在此解決方法中,使用 Apps Script API 和 Drive API 檢索庫端的所有腳本。
在此示例中,使用了 Apps 腳本 API。 因此,當您使用此腳本時,請將 Google Cloud Platform Project 鏈接到 Google Apps Script Project。 參考並且,請在 API 控制台啟用應用程序腳本 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 的容器綁定腳本,該腳本也可以工作。
在此示例中,使用了驅動器 API。 因此,當您使用此腳本時,請在 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' ]
。
在這種情況下,不會自動解析 function 名稱。 但 Google Apps Script Project 不需要與 Google Cloud Platform Project 鏈接。 但是,當庫是 Google Docs 的容器綁定腳本時,不能使用該腳本。 在這種情況下,當庫僅為獨立類型時,可以使用此腳本。 請注意這一點。
在此解決方法中,庫端的屬性和函數使用 object 進行包裝。
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: [Function: method2] }
和[ 'constructor', 'method1' ]
。Google Apps 腳本是 V8 的自定義嵌入,因此它使用 V8 C++ API 來創建“魔法”對象。 最終結果類似於代理:如果您知道屬性的名稱,則可以檢索它; 但是沒有內置的方法來枚舉庫中的可用函數。 (我不知道為什么它是這樣設計的。)
如果您控制有問題的庫,一種可能的解決方法是從那里導出函數列表:
// MyLibrary:
Object.defineProperty(this, "global", {value: this});
function getExports() {
let result = [];
let descriptors = Object.getOwnPropertyDescriptors(global);
for (let p in descriptors) {
if (descriptors[p].enumerable) result.push(p);
}
return result;
}
// main project:
console.log(MyLibrary.getExports());
(如果您不控制圖書館,@Tanaike 的回答會提供一些建議。)
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.