[TOC] > Tue Jun 29 2021 00:04:54 GMT+0800 (GMT+08:00) 我自己也是萌新,代码的世界……哈喽,世界! 真正的大佬要么在忙着工作,要么在养老,他们极少有人愿意花时间去码字,只有我这种自以为很NB的人在“哗众取宠”…… 我们来看看大家对 WPS 支持 JS宏 这件事情都有什么误解和期待? > 注意,我说的是 WPS JS 宏(软件客户端宏),不是 WPS JS 加载项。 ## WPS JS宏支持引入 JS 吗? 宏编辑器中有 "import", 试了又试,反正跑步起来……也许是我不会用 > 讨论: > > 其实引入外部 JS 并不实用,分享文件的时候总不能老是额外发一份 JS 文件吧。 如果可以,直接写进模块中即可。 > > 但总归是一个需求,也许后面会支持吧。 ## WPS JS宏支持"字典"吗? > 最佳解决方案:使用 `Lodash`,详见本书:【`将 Lodash 装进 WPS JS宏`】 字典;VB 中的 Dictionary 对象,存储数据`键/项对`,也叫“`键/值对`”、`Key/Value`;那 WPS JS宏支持吗?答案是支持。 通常在 VBA 中使用 Dictionary 对象主要是利用它“键”唯一的特性,以及用来存储一些结构性的数据。 JavaScript 的 Object 天然具有 Dictionary 对象的特性,你可以选择跟 Dictionary 对象更类似的 JSON。 > 这是个伪命题,在 JavaScript 中使用 JSON,就是 JSON Object 化,终点依旧在 Object 上。 **`注意`**: > JavaScript 的 Object 虽然有 Key/Value 特性,但 JavaScript Object 和 VB 的 Dictionary 对象不是同一类东西。 毫不夸张地说,JavaScript 在 Key/Value 方面,简直就是神一般的存在——不得不承认,我夸张了。JavaScript 弱类型的特性就很棒…… 在 VBA 中,使用 Dictionary 之前你得: ```vb Set dir = CreateObject("Scripting.Dictionary") ``` 然后才能: ```vb dir.Add "fir", "Hello,World" ``` 在 JavaScript 中就没这么麻烦了…… ### 简单! ```js // 走走形式 let foo = {} foo.assigin({fir:"Hello!World"}) Console.log(foo.fir) ``` 还可以是这样的: ```js let foo = { bar:function(){ return "Hello,World!" } } // 当然,这里一点都不 "字典" foo.bar() ``` > 除了 Key 有限制外,Value 可以是任何类型……它可以更复杂地嵌套: ```js let kv = { a:{ a1:{ a11:{ bar:[1, 2, 3] }, a12:{ amHere:"hello", a12_1:{}, // 可以继续 } } }, b:{}, c:{}, d:{} } // 嵌套太深,会累死的;因为 // 当你要获取"hello" 时: let hi = kv.a.a1.a12.amhere; // 就,就很长…… ``` 如果你真的喜欢 Key/Value,那么你可以尽情发挥: ```js let data = { a:[ {"a1": "a1"}, {"a2": "a2"}, {"a3": "a3"}, {"a4": [ {"gogo":[ {"a": 1}, {"b": 2} ]} ]} ], b: "hello", c: null, d: false, e: true } ``` ### 不够?可以直接上 JSON > [了解什么是 JSON?](https://www.json.org/json-es.html) 核心: 1. `JSON.parse` ,解析 JSON 结构字符串;可以理解为 JSON 转 JavaScript 对象; > JSON --> JavaScript Object 2. `JSON.stringify` ,JavaScriptn 对象 JSON 化,可以理解为 JavaScript 对象转 JSON。 > JavaScript Object --> JSON ```js function _m_json() { Console.clear() let jsonContent = ` { "KV":{ "a": 1, "b": "1", "c": "Hello", "a-b": "a-b", "a_b": "a_b", "a b": "a b" } } `; let obj = JSON.parse(jsonContent) Console.log(obj.KV.a) Console.log(typeof (obj.KV.a)) Console.log(obj.KV["a-b"]) // ------- let foo = { a:1, b: null, c: undefined, d: false, e: "1", f: /[az]/g, g: "hello", h: (function (){ let p = new Date().getMonth() return p })(), } let foo2json = JSON.stringify(foo) Console.log(foo2json) } ``` 运行之后,有何发现? ### 键值对更改 VB 中 Dictionary 对象有 Remove/RemoveAll 方法,可以操作Key/Value条目;在 JS 中则可以用 delete 方法。我们来看看 ```js function _m_jsObject(){ dir = { "1": 1, "2": 2, "3": 3 } delete dir["3"] // 删除"3"属性。 Console.log(dir["3"]) } ``` > 其实,我们很少会这么干,关于 [delete 更多介绍](https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Operators/delete) 通常地,你只需读取你要的就可以了,并不总是需要将其删除;比如,只读取 Key 为"1"、"2" 的项的值,则: ```js let foo = [ dir['1'], dir['2'] ] ``` 为什么不删呢?因为删变量、对象的属性影响是巨大的,看看下面的例子: ```js function _m_why() { let foo = { a: 1, b: 2, c: 3 } let bar = foo; delete bar.c // 把 bar.c 删掉 // 获取所有的 Key let keys_foo = Object.keys(foo) let keys_bar = Object.keys(bar) // 输出 key 的个数 Console.log(keys_foo.length) // 2 Console.log(keys_bar.length) // 2 } ``` > 找到原因了吗? 因为我们并不总是能时刻保持严谨,所以每当要"删除"的时候都很谨慎。甚至偷懒不删……下面来看看更新 Kay、Value的操作: ```js function _m_changeObject() { let foo = { a: 1, b: 2, c: 3 } // key c 改为 bar; // 不介意 foo 的属性个数变多的改法: foo['bar'] = foo.c Console.log(`foo.bar --> ${foo.bar}`) // 新建对象 let tar = { a: foo.a, b: foo.b, bar: foo.c } // 以上的做法,foo.c 一直都在…… // 更改 Value foo.a="123"; Console.log(foo.a) } ``` > 注意 let、var、const 声明之间的区别,并不是什么都可以改的。 属性名(Key),通常我们都不会去动它,因为没有多大意义——我们只是需要这个key(属性)所代表的值;如果需要存储的数据键值对的key和Value都是有意义的,那么最好将将它们都作为 Value来存储,而不是将其中之一作为Key另一个作为Value,看下面的例子: ```js let vipMembers = { /* 这种做法,key成为数据的一部分 key自然很重要,但不建议,因为在 JavaScript 中,会发生key(属性名)丢失的情况—— 当你使用某些 JS 扩展库时*/ zhangSan:{ name:"张三", age: 30 } } // 不要将它们拆开: let vipMembersA =[ { userName: "zhangSan", vipname:"张三", age: 30 } ] /* let vipMembersA ={ "1":{ userName: "zhangSan", vipname:"张三", age: 30 }, "2":{ //... } } */ ``` ## WPS JS宏支持 JQuery 吗? JQuery,操作 DOM 的,WPS JS 宏并没有 DOM 可操作,不支持。 ## WPS JS宏支持 Node.js 吗? Node.js 是 JavaScript 运行时,WPS JS宏也有自己的运行时,理论上 WPS JS 并不能使用用于 Node.js 的 JS 代码。 ## WPS JS宏支持文件读写吗? 应该正在支持,只是还没有示例——甚至没有写进开发文档里:是已经支持只是没有更新开发文档,还是没有完成?无处得知…… 不过,Open、Write、CurDir 等和 VB 一样的方法是已经有了的,只是缺少一个官方示例…… > WPS JS 加载项是已经支持了的。 ## WPS JS宏支持 Lodash 吗? **`支持`** ! 因为 Lodash 只是对 Array、Object 等标准 JavaScript 内置对象的扩展,不涉及其他 JS 库 API(比如 Web API、DOM等),所以可以直接用。你可以直接把 Lodash 发行版源码拷贝到 WPS JS宏模块中(也可以进行自定义定制构建打包)然后使用,参考本书 【`将 Lodash 装进 WPS JS宏`】章节。 ## WPS JS宏支持 Ajax、Axios 吗? WPS 客户端 JS宏 API 没有提供网络通信协议支持,所以任何基于 HTTP/HTTPS 网络协议的 JS 库都不被支持。XMLHttpRequest 并不是标准 JavaScript 内置对象/方法,它属于 WEB API。 ## 总之 还是那句话:仅支持标准 JavaScript 扩展库和 WPS JS API 的自身扩展库(比如对现行 WPS 软件客户端 JS API 的进一步拓展和封装) > WPS JS 加载项可以使用能运行在浏览器中的绝大多数 JS 库,覆盖率和浏览器基本一致。