This shows you the differences between two versions of the page.
Both sides previous revision Previous revision Next revision | Previous revision | ||
JXA_JavaScript_for_Applications [2016/01/05 15:12] ComplexPoint [Attaching reusable names to evaluations and their results:] |
JXA_JavaScript_for_Applications [2016/01/06 21:17] peternlewis deleted in favor of JavaScript for Automation |
||
---|---|---|---|
Line 61: | Line 61: | ||
| <code>count of documents of application "TextEdit" </code> | <code>Application("TextEdit").documents.length </code> | | | <code>count of documents of application "TextEdit" </code> | <code>Application("TextEdit").documents.length </code> | | ||
- | ====Attaching reusable names to evaluations and their results:==== | + | ====Attaching reusable names to computations and their results:==== |
- | If we often need to calculate the Golden Ratio, we can attach a name to its computation, and reuse it by that name. Nameable computations are called 'handlers' in AppleScript, and 'functions' in JavaScript. | + | If we often need to calculate the [[https://en.wikipedia.org/wiki/Golden_ratio|Golden Ratio]], we can attach a name to its computation, and reuse it by that name. Nameable computations are called 'handlers' in AppleScript, and 'functions' in JavaScript. |
===Named computations – handlers and functions=== | ===Named computations – handlers and functions=== | ||
Line 111: | Line 111: | ||
^ AppleScript ^ JXA ^ | ^ AppleScript ^ JXA ^ | ||
| <code>on goldenRatio(n) | | <code>on goldenRatio(n) | ||
+ | |||
return (((sqrt 5) + 1) / 2) * n | return (((sqrt 5) + 1) / 2) * n | ||
+ | | ||
end goldenRatio | end goldenRatio | ||
- | |||
- | |||
Line 140: | Line 140: | ||
JavaScript is relaxed about whether we supply an argument or not. If we don't, the name ''n'' will have the special value ''undefined'', which takes on the value ''false'' in a logical expression. Above we are using the [[https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Logical_Operators|JavaScript logical operator OR ( || )]] to attach the name n to the value 1 if no argument has been supplied. | JavaScript is relaxed about whether we supply an argument or not. If we don't, the name ''n'' will have the special value ''undefined'', which takes on the value ''false'' in a logical expression. Above we are using the [[https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Logical_Operators|JavaScript logical operator OR ( || )]] to attach the name n to the value 1 if no argument has been supplied. | ||
- | ===Named results of computations – variables which hold values=== | + | ===Named results of computations – 'variables' which hold values=== |
+ | |||
+ | In addition to reusable names for particular computations and their arguments, we can also give names to the results of computations. Once a result is stored in a named variable, we can reuse it without having to recalculate it. | ||
+ | |||
+ | ^ AppleScript ^ JXA ^ | ||
+ | | <code>on run {} | ||
+ | set phi to (((sqrt 5) + 1) / 2) | ||
+ | set phi18 to phi * 18 | ||
+ | set phi7 to phi * 7 | ||
+ | |||
+ | return phi18 + phi7 | ||
+ | end run | ||
+ | |||
+ | --> 40.450849718747</code> | <code>function run() { | ||
+ | var phi = (Math.sqrt(5) + 1) / 2, | ||
+ | phi18 = phi * 18, | ||
+ | phi7 = phi * 7; | ||
+ | |||
+ | return phi18 + phi7; | ||
+ | } | ||
+ | |||
+ | // --> 40.45084971874737</code>| | ||
+ | |||
+ | |||
+ | ==Things to notice – 1. We gave the name 'run' to a computation, and it 'ran' without being called …== | ||
+ | |||
+ | In osascript (AppleScript or JXA), **run** is a special name. A handler or function with that name is called automatically – you don't have to append parentheses to call it, like we did with the **goldenRatio** computation. | ||
+ | |||
+ | In fact, when we don't assign any names to computations (don't create any AS handlers or JS functions), osascript automatically wraps our our script in a computation which it names **run**, and immediately calls it. | ||
+ | |||
+ | ==Things to notice - 2. We are attach names here to some results of computations== | ||
+ | |||
+ | The following names are all given to the result of a computation, rather than to a computation or argument: | ||
+ | |||
+ | - phi | ||
+ | - phi18 | ||
+ | - phi7 | ||
+ | |||
+ | ==Differences to notice: AS and JS use different patterns for naming results== | ||
+ | |||
+ | Where AS uses the pattern: **set** *name* **to** *resultingValue* (and reserves **=** for testing equality), | ||
+ | |||
+ | JS uses one or more [[https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Statements/var|variable declaration statements]] (and [[https://developer.mozilla.org/en-US/docs/Web/JavaScript/Equality_comparisons_and_sameness|tests equality]] with **===**) | ||
+ | |||
+ | In JS we can either: | ||
+ | |||
+ | - group several variable declarations together (separated by commas, finishing with a semicolon – example above), | ||
+ | - use a separate variable declaration statement for each variable, or | ||
+ | - make our lives more complex by using the names without a var declaration | ||
+ | |||
+ | ^ Good and simple JXA – temporary local names ^ Messy and complex JXA – persistent global names ^ | ||
+ | |<code> var phi = (Math.sqrt(5) + 1) / 2, | ||
+ | phi18 = phi * 18, | ||
+ | phi7 = phi * 7; | ||
+ | // or | ||
+ | var phi = (Math.sqrt(5) + 1) / 2; | ||
+ | var phi18 = phi * 18; | ||
+ | var phi7 = phi * 7;</code>|<code> phi = (Math.sqrt(5) + 1) / 2; | ||
+ | phi18 = phi * 18; | ||
+ | phi7 = phi * 7;</code>| | ||
+ | |||
+ | |||
+ | JavaScript gives us a lot of freedom, [[http://shop.oreilly.com/product/9780596517748.do|sometimes more than is helpful]]. Misspelled variable names, and accidental uses of the same globally visible name in different parts of a script are rich sources of puzzling bugs and wasted time. To use a less liberal but more helpful set of JavaScript rules, we can add the line **'use strict';** | ||
+ | at the start of a function. When we do this, JavaScript checks that all of our variables are declared (and therefore 'local' – visible only to their containing functions, and also temporary – vanishing when the evaluation of a function is completed). If an undeclared variable name is detected when the **'use strict';** statement has been added, we are given a helpful warning: | ||
+ | |||
+ | {{::use-strictpng.png|}} | ||
+ | ====Structuring collections – indexing by number, and by name=== | ||
+ | |||
+ | to follow ... | ||
+ | |||
+ | ====Structuring computations – branching, repetition, and nested composition==== | ||
+ | |||
+ | to follow ... | ||
+ | |||
+ | ====JSON for persistence – saving things between macro runs, and reading them straight back in==== | ||
+ | |||
+ | to follow ... | ||
+ | |||
+ | =====The Automation interface===== | ||
+ | |||
+ | ===Using the Standard Additions library==== | ||
+ | |||
+ | to follow ... | ||
+ | |||
+ | ===Interacting with scriptable applications=== | ||
+ | |||
+ | to follow ... | ||
+ | |||
+ | =====Using the Safari JSContexts Debugger (El Capitan onwards)===== | ||
+ | |||
+ | to follow ... | ||
+ | |||
+ | =====The ObjC interface===== | ||
+ | |||
+ | to follow ... | ||
+ | |||
+ | ===Basic file functions=== | ||
+ | |||
+ | to follow ... | ||
+ | |||
+ | ===Clipboard functions=== | ||
+ | |||
+ | to follow ... | ||
- | (to be added) | + | ===Reading the documentation for simple ObjC functions=== |
+ | to follow ... |