User Tools

Site Tools


JXA_JavaScript_for_Applications

Differences

This shows you the differences between two versions of the page.

Link to this comparison view

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 ...