忍者ブログ

ぼんぷろぐ

InDesignとかイラレとかのスクリプトよもやま話

新しいブログに引っ越しました。

こちらのブログはもう更新しませんが、コメント欄は生きてますので疑問、ご指摘などありましたらどうぞ。

[ExtendScript]
ExtendScriptのココがJavaScriptじゃないよ

(追記)なんかごちゃごちゃしてるのでこっちにまとめ直しました


ExtendScriptの独自のものとか、JavaScriptの仕様に反するようなものを知ってる限りあげてみました。といっても1.以外はほんとに重箱の隅みたいなのばかりです。何かほかにもありましたらぜひコメントくださいませ。(「今時のJavaScriptにあるこんな機能がExtendScriptにはない」っていうのは対象外です)

1. File,Folder,Socket,BridgeTalk,UnitValue,$,ScriptUIが使える

Extendというだけあって、様々な組み込みオブジェクトで機能が拡張されています。
File、Folderはそのまんまファイルとフォルダが扱え、SocketはTCP/IP通信、BridgeTalkはアドビアプリの間の通信、UnitValueは長さの単位がついた値の演算や単位変換ができます。$は主にデバッグに使うヘルパーオブジェクトです。ScriptUIはダイアログとかを作るアレです。

2. XMLが使える

XMLを扱うことができます。なんで1.にまとめなかったのかと言えば、独自のリテラル(表記方法)や演算子があることと、XMLがBoolean,null,undefined,Number,String,Objectに次ぐ第7の『型』であることからです。
この機能はE4Xと呼ばれる、ECMAScriptの拡張であるECMA-357に基づいたものであるようです。一時期Firefoxなどでも使えたようですが、今は廃止されています。

3. """でヒアドキュメント

通常『"』1つで囲む文字列を3つにすることで改行やタブなどがそのまま有効な文字列になります。こういうのをヒアドキュメントって言うそうです。

4. 入れ子の三項演算子の実行順序

たとえば 1?2:3?4:5 という式を評価した場合、JavaScriptでは 1?2:(3?4:5) の意になり 2 が返りますが、ExtendScriptでは (1?2:3)?4:5 の意になり 4 が返ります。
1?2?3:4:5 はJavaScriptでは 1?(2?3:4):5 の意になり 3 が返りますが、ExtendScriptでは構文エラーになります。
こいつはJavaScriptのライブラリを取り込みたいときの障害になることがしばしばあります。

5. 関数を即時実行したときのthis

関数内のthisは、オブジェクトのメソッドとして実行したときはそのオブジェクト、newをつけたときは新規オブジェクト、callやapplyで呼び出したときは引数で指定したオブジェクト、それ以外はグローバルオブジェクトになる、というのがJavaScriptの仕様です。
となると
g=(function(){return this})();
を実行するとgにはグローバルオブジェクトが入るはずなのですが、なぜかExtendScriptでは関数自身が入ります。

6. Function()を使ってもクロージャになる

関数はfunction式やfunction宣言で定義すると、定義を行ったスコープのクロージャになりますが、Functionコンストラクタを使って定義した場合はクロージャにならない(グローバルスコープのクロージャになるとも言える)というのがJavaScriptの仕様です。しかしExtendScriptではfunction式などと同じくクロージャになります。
たとえば
var a=1;
(function(){
    var a=2;
    return Function("alert(a)");
})()();
はJavaScriptでは1が表示されますがExtendScriptでは2が表示されます。

7. 演算子のオーバーロードができる

一部の演算子は、オブジェクトにその演算子をプロパティ名とする関数プロパティを追加することで、演算の仕方を定義することができます。

//演算によりダイコンをラジコンに変換する例
var obj={
    name:"",
    "-":function(s){
        this.name=this.name.replace(s," ");
        return this},
    "+":function(s){
        this.name=this.name.replace(" ",s);
        return this},
};
obj.name="ダイコン";
obj-"ダイ"+"ラジ";
alert(obj.name); //ラジコン

詳しくはこちらを(英語)
http://www.indiscripts.com/post/2010/05/operator-overloading-with-extendscript

8. 細かいバグ

null==false
は true なのに
x=null,x==false
は false になるとかいうのはさすがにバグと言っちゃっていいでしょう。JavaScript的に正しいのはfalseの方です。

(2018.07.31 ここから追記)

9. const宣言

const(定数)宣言が使えます。varとの違いは「値を変更しようとするとエラーが出る」だけです。
・varと同様の変数の巻き上げが起こる
・ブロック単位のスコープを作らない
という点でECMAScript6のconstとは異なるので注意が必要です。というか使わなくていいと思います。

10. reflectプロパティ

すべてのオブジェクトがreflectプロパティを持っています。中身はオブジェクト自身に関する情報が入ったReflectionオブジェクトです。
reflect.nameでオブジェクトの種類を判別したり、reflect.propertiesやreflect.methodsでプロパティ名やメソッド名の一覧を得ることができます。

11. =の左辺と右辺が評価される順番

Marc Autretさんがツイートしておれらます。
https://twitter.com/indiscripts/status/937164479040811009

JavaScriptでは左辺→右辺
ExtendScriptでは右辺→左辺の順で評価されるようです。
PR

コメント

お名前
タイトル
文字色
メールアドレス
URL
コメント
パスワード Vodafone絵文字 i-mode絵文字 Ezweb絵文字

無題

関数の外でvarをつけてもグローバル変数になるというのは5、6あたりと同じことでしょうか。
var a = "original";
test();
alert(a);
function test() { a = 123; }

もう1個

これはバグ。
var str1 = "星稜14-9遊学館";
var reg = /([0-9]+)\-([0-9]+)/;
//str1.match(reg);
str1 = str1.replace(reg, RegExp.$2 + "-" + RegExp.$1);
$.writeln(str1);
$1~$9にすぐに値が入らないバグ。3行目のコメントを外せば(1回検索しとけば)入ってくれる。

Re:もう1個

お~まち様、コメントありがとうございます。いつもDOMにお世話になってます

どちらもJavaScriptの仕様通りだと思います。たとえばalert(1+1)を実行すると、まず1+1が評価され、その結果の2を関数alertに渡してアラートが出ます。同じように関数replaceが実行されるのは引数の式「RegExp.$2 + "-" + RegExp.$1」が評価されるよりも後です。
これをやるなら第2引数に関数を使って
str1 = str1.replace(reg, function($0,$1,$2){return $2+"-"+$1});
のようにするといいです。

1つ目の方はどういう挙動が正しいと思っておられるのかよく分からないですが、JavaScriptで関数の外でvarをつけて宣言した変数はまさにグローバル変数です。

  • kawamoto_α
  • 2017/07/19(Wed.)

Re:もう1個

ありがとうございます。私今までずっと勘違いしてました。勉強しなおしです。

三項演算子についてご質問

先ほどコメントで質問をさせいただいたのですが、こちらの理解が不足していたため消去いたしました。
お騒がせして申し訳ありません。
どうぞご放念下さいませ。

プロフィール

kawamoto_α
(あるふぁ(仮))


InDesignで新聞組版のようなことをしています。

ツイッタ

※ブラウザによっては当ブログからDLしたzipファイルが拡張子なしになることがあるようですが、.zipを補って開いてください。



イラレ用トーンカーブスクリプト(¥1500)



クロソイド式角丸長方形スクリプト(¥500)
Illustrator用
InDesign用



イラレスクリプトをキーボードショートカットで実行するやつ(Win用)