javascript - 如何遍历 v8 中全局对象(库)的所有属性/函数?

标签 javascript google-apps-script libraries v8 global-object

Google 应用程序脚本提供了一个 library feature ,如果您包含项目 key ,则会将库添加为全局对象。我正在寻找迭代添加库的所有功能。这曾经在 中是可能的带有 for...in 循环的引擎。但我无法遍历 中的库的任何属性引擎。

documentation

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
  • 将上面的脚本复制粘贴到项目A中,选择testLib函数并点击运行

最佳答案

问题和解决方法:

我一直在寻找在启用 V8 的情况下从客户端直接检索库端的属性和函数的方法。但不幸的是,我仍然找不到它。因此,就我而言,我使用了 2 种解决方法。

  1. 使用 Apps Script API 和/或 Drive API 检索所有脚本。

  2. 将属性和函数包装在一个对象中。

通过上述解决方法,可以从客户端检索库端的属性和函数。

解决方法 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/

相关文章:

javascript - 在响应式环境中组合(叠加)一堆图片的方法?

javascript - 根据 "Data attributes"和disabled-attribute禁用一组复选框

JavaScript 事件监听器与隐藏的 DOM 元素交互

google-app-engine - 在 Google 电子表格中标记重复条目

javascript - regionCode 无法始终正常工作,YouTube API,Google App Script

typescript - 缩写冗长的 TypeScript 类型

c++ - 如何在 C++ 中为 Windows 的 GDI 正确设置库?

javascript - 为什么不在 2017 年将 Array.prototype 方法添加到 NodeList.prototype 中?

javascript - 跨网站缓存Javascript库

javascript - 什么时候应该在 if 语句的条件内使用括号?