Python 使いのための Javascript に関するノート
Python と Javascript はシンタックスの上で大きな違いがあるが、内面ではこの二つはよく似ている。
* | Python | Javasript | comment |
---|---|---|---|
look inside | dir(m) |
? | m : module,object |
型 | type(o) |
typeof(o) |
o : object |
no value | None |
undefined null |
|
論理値 | True , False |
true , false |
|
print x |
document.writeln(x) |
x : object |
|
creation | a = 3*[] |
a = new Array(3) |
|
size | len(a) |
a.lengh |
a : sequence |
first element | a[0] |
a[0] |
a : sequence |
last element | a[-1] |
a[a.length - 1] |
a : sequence |
slice | a[n:m] a[n:] |
a.slice(n,m) a.slice(n) |
a : sequence |
* | Python | Javasript | comment |
---|---|---|---|
find s in a | a.find(s) a.index(s) # raise error |
a.index(s) a.find(s) |
a : string |
rfind s in a | a.rfind(s) a.rindex(s) # raise error |
a.rindex(s) |
a : string |
replace p by r | s.replace(p,r[,n]) |
s.replace(p,r[,f]) |
p ,r : string, n : count, f : flag |
* | Python | Javasript | comment |
---|---|---|---|
準備 | import re |
不要 | |
compile | c = re.compile(p[,f]) |
c = new RegExp(p[,f]) |
p : pattern, f : flag |
match | c.match(s) re.match(p,s) |
s.match(c) s.match(p) |
p : pattern |
replace | c.sub(r,s) re.sub(p,r,s) |
s.replace(e,r) |
p : patterne : re, r : string |
match の振る舞いは Python と Javascript でかなり違う。例えば
Python:
re.match("b","abc") # return NoneJavascript:
"abc".match("b") // return "b"実は Javascript の match は Python の search に近い。
m = re.search("b","abc") # match m.group() # return "b"Javascript の match も Python の search も共にマッチした全てのグループの情報を返すが、Javascript の match はグループの情報を文字列の配列として返す。他方 Python の search は位置情報の配列を返す。Python に於いてはマッチした文字列情報は group() メソッドで得られる。
Python の厳格さに比べて Javascript はプラクティカルな簡便さを追求している。それを示す代表的な例は、
Python:
re.search("","abc") # match re.search(None,"abc") # errorJavascript:
"abc".match("") // match "abc".match(null) // null長さ 0 の文字列はどのような文字列の部分文字列となり得る。他方「存在しないものは探せない」ので、Javascript の「ありませんでした」は使いやすい。(論理式の中で使う事を想定せよ。)
* | Python | Javasript | comment |
---|---|---|---|
初期化 | a = [] a = [None]*3 |
a = new Array() a = new Array(3) |
|
代入 | a[n] = v |
a[n] = v |
n : integer(>=0), v : value |
サイズ | len(a) |
a.length |
|
要素の追加 | a = a + [v] a.append(v) |
a.push(v) |
v : value |
ソート | a.sort() |
a.sort() |
Javascript では配列のインデックスに文字列を使える。これは実際には辞書である。
正しくは文字列だけではなく、Python と同様に任意の object が使える。
* | Python | Javasript | comment |
---|---|---|---|
初期化 | d = {} |
d = new Array() |
|
割り付け | d[o] = v |
d[o] = v |
o : object, v : value |
サイズ | len(d) |
d.length |
x=Noneのように、"
None
" を割り当てておく。Python の None
に相当する Javascript の定数は null
である。
Javascript はブラウザの中で使用される。現実はブラウザの Javascript の実装状態が均一ではない。あるブラウザが、ある変数 foo
を持っていても、他のブラウザでは持っていない事がある。変数 foo
を持っていない場合にだけ、何かを行いたい場合にはどうするか?
仮に Python で(無理に)変数が定義済みである事を知りたいなら注1、次のような関数 defined()
を定義すればよい。
Python:
def defined(s): try: eval(s) except: return False return True if not defined("foo"): # do somethingJavascript では未実装の変数を認識するニーズがあるのだから簡単に行えるようになっている。
if(foo == undefined){ alert("undefined"); }としても alert("undefined") は実行されない。この if 文の論理式はエラーなのである。正しくは
if(typeof(foo) == "undefined"){ // do something }とする。
Javascript の typeof
は一種のマクロ関数的な振る舞いをするのだね。普通の関数であれば、未定義の変数を引数に与えたらその関数の実行はできないのだから。typeof
はその意味で関数ではない。
そう言えば僕は屢々誤解のために混乱したものだ。デバッグの時に
alert(foo)のようにやる。
foo
が定義されているのか否かがこれで分かると思って... そして頭の中は "???" だ。この場合にはalert(typeof(foo))としなくてはならない。
注1: 「無理に」と言ったのは、Python では未定義の変数を参照すれば実行時に分かるので、判定の必要は無いと考えているからである。
x in aについて考える。
a=["alice","bob","carol"] for x in a: print x出力
alice bob carol
Javascript:
a=new Array("alice","bob","carol"); for(x in a){ document.writeln(x) }出力
0 1 2ちなみに上の変数
a
の下で Python では"alice" in aは
True
であるが、Javascript では false
で、1 in aは Python では
False
であるが、Javascript では true
である。
この例を見る限り Javascript はいかにも奇怪であるが、次の例を見ると納得できるであろう。
a=new Array(); a["alice"]=16; a["bob"]=20; for(x in a) document.writeln(x)これは
alice bob trueを出力する。Python では連想配列は辞書を使う。
a={} a["alice"]=16; a["bob"]=20; for x in a: print x print "alice" in aで
alice bob Trueを出力。つまり Javascript で「配列」と称せられるものは Python の辞書であると解釈できる。
function names(s){ var n,x,t,w,a; a = new Array(); for(x in s){ a.push(x); } a.sort(); t = ""; for(n = 0; n < a.length; n++) t += a[n] + "\n"; // NG: alert(t) ; because the out put is big and therefore "OK" button is hidden. // so we must show the t in other windows. w = open("","Names","width=400,scrollbars=yes,resizable=yes"); cont = "<html><head><title>Names</title></head><body><pre>"; cont += t; cont += "</pre></body></html>"; w.document.write(cont); w.focus(); w.document.close(); }names(window.document);