java.lang.StringとString.prototypeの関係
命名規則でクラスについては大文字それ以下は小文字というルールを決めているのでPHPとかでいうucfirst関数を書いているのですが型がJavaのjava.lang.StringだとcharAtを利用するとうまく行かないという話。jrunscriptで検証。
String.prototype.ucfirst = function(){ return this.charAt(0).toUpperCase() + this.slice(1); }; foo = 'foo'; foo.ucfirst(); // Foo ← 問題無 bar = new java.lang.String('bar'); bar.ucfirst(); script errot: (中略) : Type Error: Cannot find function toUpperCase.
toUpperCaseが見つからない...
結論から言うと、String.prototype拡張であっても型がjava.lang.Stringの場合にはcharAtを利用すると本当にcharを返すのでJavaScriptではNumberになる為に見つからくなる。加えて、どうやらECMAScript標準のScript.prototype.charAtではなくてjava.lang.String#charAtが優先的に利用されているようである。
String.prototype.test = function(){ return charAt(0); }; bar.test(); // 102 /* ECMAScript String#length は プロパティ JavaのString#length は メソッド */ String.prototype.testLength = function(){ return this.length(); }; new java.lang.String("foo").testLength(); // 3 "foo".testLength(); // error
まとめとして...
その後色々したあげくjava.lang.String型をJavaScriptから操作する場合には
- String.prototype の拡張して利用可能である。
- java.lang.Stringに同一のフィールド(メソッド/プロパティ)があればそちらが優先される。
- java.lang.Stringに該当するフィールドが無い場合はECMAScriptネイティブのString.prototypeが利用される(といいつつcharCodeAtくらいしかない。)
ucfirst
String.prototype.ucfirst = function(){ return this.slice(0,1).toUpperCase() + this.slice(1); };
あ〜今日でテスト終了...。いろいろな意味で終わったな。北海道にあと1年か...な(--;