在Javascript for Automation中使用"which"数组

Ben*_*tto 5 applescript osx-yosemite javascript-automation

使用脚本编辑器使用新的JS进行自动化.我在下面的最后一行收到错误:

var iTunes = Application("iTunes");
var sources = iTunes.sources();
var library = sources.whose({name : "Library"});
Run Code Online (Sandbox Code Playgroud)

确认sources数组是预期的(两个元素,一个带有name"Library"和一个"Internet Radio").但最后一行扼杀了Error on line 3: TypeError: undefined is not a function (evaluating 'sources.whose({name : "Library"})').

据我所知,我正在使用正确的whose函数语法.(我也尝试使用明确的_equals条款来得到相同的结果.)我做错了什么?

foo*_*foo 8

我究竟做错了什么?

简短的回答:这不是你的错.JXA文档是一堆谎言.

更长的解释:对象的元素与数组无关.它们表示对象图中的一对多关系,在这种情况下,在source对象与零个或多个library对象之间.

虽然许多关系可能反映了基础实施的遏制等级,但没有义务这样做; 例如,Finder允许您以多种方式识别桌面上的对象:

items of folder "Desktop" of folder "jsmith" of folder "Users" of disk "Macintosh HD" of app "Finder"
items of folder "Desktop" of folder "jsmith" of folder "Users" of startup disk of app "Finder"
items of folder "Desktop" of home of app "Finder"
items of folder "Macintosh HD:Users:jsmith:Desktop" of app "Finder"
items of desktop of app "Finder"
items of app "Finder"
[etc.]
Run Code Online (Sandbox Code Playgroud)

基于Apple事件的应用程序脚本基于远程过程调用和简单的第一类查询.它不是 OOP,不管表面外观:这只是语法糖,使其查询易于读写.

...

在这种情况下,您的第二行是告诉iTunes获取一个查询对象(ObjectSpecifiers)列表(Array),用于标识sourceiTunes应用程序中的每个对象:

var iTunes = Application("iTunes");
var sources = iTunes.sources();
Run Code Online (Sandbox Code Playgroud)

一旦有了Array,就不能用它来构造更多的查询,因为JavaScript本身并不知道如何构建查询.你真正想要的是这个:

var iTunes = Application("iTunes");
var sourcesSpecifier = iTunes.sources;
var librarySpecifier = sourcesSpecifier.whose({name : "Library"});
Run Code Online (Sandbox Code Playgroud)

这将为您提供一个对象说明符,用于标识source名称为"Library"的所有对象.(如果您只想指定名为"Library" 的第一个 source对象,请使用该byName方法而不是whose;它更简单.)

-

就个人而言,我认为所有这些都是学术性的,因为JXA的Apple事件桥实现,就像它的文档一样,主要是由Lame和Fail组成.它主要是在一定程度上工作,然后在你之上大肆宣传.如果你的需求是适度的,而且"足够好"可以为你做更多的力量,但对于AppleScript的任何非常重要的事情:它是唯一可行的支持解决方案.

(AppleScript/JXA团队也没有理由做这样的垃圾工作:几个月前我给他们发了一个几乎完成的JavaScriptOSA参考实现,他们希望学习或偷窃,他们完全忽略了.所以你可以原谅我的小便,就像这是很久以前解决的问题.)

  • 呵呵.设置脚本编辑器的结果窗口以显示传出事件证明是指导性的.即使是最简单的用例,`Application("iTunes").sources.whose({name:'Library'}).get()`,不知何故被解释为`app.sources.whose({name:"Library"} ).sources.byName( "获取")()`.换句话说,它已经破碎了.我甚至都不打算猜测它是如何设法达到这个废话的 - JXA的整个AE桥和OSA组件实现是如此根本无能,它唯一能够正常工作的方法就是抛出全部并从头开始重做. (2认同)

hou*_*ker 2

现在这正如理论预测的那样起作用。

(function () {
    'use strict';

    var iTunes = Application('iTunes'),
        filtered = iTunes.sources.whose({
            name: 'Library'
        });

    return filtered().length;

})();
Run Code Online (Sandbox Code Playgroud)