JavaScript勉強中

『パーフェクトJavaScript』の5章を読んでいます。

トップレベルのthisにはグローバルオブジェクトが格納されている。

js> this;
[object global]
js> function foo() { print(this); }
js> foo();
[object global]
js> new foo();
[object Object]
[object Object]

new foo()で[object Object]が2回表示されているのは、print()による表示と、new foo()の戻り値の表示のため。

Mathオブジェクト。

js> Math.max(1, 2);
2
js> Math.max(1, 3, 5, -3);
5
js> Math.PI;
3.141592653589793
js> Math.floor(1.2);
1
js> Math.floor(-1.2);
-2
js> Math.ceil(1.2);
2
js> Math.ceil(-1.2);
-1
js> for (var i = 0; i < 5; i++) print(Math.random());
0.4456297162906472
0.6057992880609755
0.4319719921732187
0.6201942707817898
0.8060875525290142

Mathオブジェクトで定義されている全てのプロパティを列挙できるだろうか。

js> for (var a in {x:1,y:2}) print(a);
x
y
js> for (var a in Math) print(a);
js> 'floor' in Math;
true

何も列挙されなかった……。やり方が違うのかな。でも、'floor' in Mathはtrueとなっている。『パーフェクトJavaScript』のp.146「5-17-5 プロパティの列挙(プロトタイプ継承を考慮)」にやり方が書いてあった。

js> Object.getOwnPropertyNames(Math);
toSource,abs,acos,asin,atan,atan2,ceil,cos,exp,floor,log,max,min,pow,random,round,sin,sqrt,tan,E,PI,LN10,LN2,LOG2E,LOG10E,SQRT1_2,SQRT2

出た。これでPythonのdir()っぽいものが作れる。

js> function dir(obj) { return Object.getOwnPropertyNames(obj); }
js> dir(Math);
toSource,abs,acos,asin,atan,atan2,ceil,cos,exp,floor,log,max,min,pow,random,round,sin,sqrt,tan,E,PI,LN10,LN2,LOG2E,LOG10E,SQRT1_2,SQRT2
js> dir(Object);
getPrototypeOf,keys,getOwnPropertyNames,getOwnPropertyDescriptor,defineProperty,isExtensible,preventExtensions,defineProperties,create,isSealed,isFrozen,seal,freeze,arguments,prototype,name,arity,length
js> dir([]);
length
js> dir({});

js> dir("");
js: uncaught JavaScript runtime exception: TypeError: Expected argument of type object, but instead had type string

js> dir(new String(""));
length
js> dir(new Number(2));

js> function Foo() {}
js> dir(Foo);
arguments,prototype,name,arity,length
js> dir(new Foo());

js> 

でも、Object.getOwnPropertyNamesは名前の通り、自身で定義してあるものを返すようだ。toStringが出力されていない。toStringはどこで定義されてあるのだろう。

js> [].toString();

js> [1].toString();
1
js> [1,2].toString();
1,2