ラベル javascript の投稿を表示しています。 すべての投稿を表示
ラベル javascript の投稿を表示しています。 すべての投稿を表示

2014年7月5日土曜日

新しいことを始めるときは。

新しいことを始めるとき。
今回は、AppMethodに挑戦なのですが、
プログラミングに限らず、新しいことを始めるときは、
大きく2つの方法があると思ってます。
(1)基礎から徹底的に学ぶ
(2)何かの目標をつくって、その最短距離を学ぶ。

もちろん、子供が勉強するかのごとく、(1)は良い方法というか、王道です。
しかし、大人がピアノを習うときは、(1)だと絶対めげちゃうんですよ。
だから、(2)なのです。
ハノンもやらず、『ピアノのテクニック』もやらず、
【弾きたい曲をなんとか仕上げる】
という方法をとるべきです。

ということで、【つくってみたいアプリをとにかく完成させる】ことを目標とし、
(2)の方法でAppMethodを学びます。
そして、都度、必要に迫られたときに、基本的なことを学びます。

ツール類は、最低条件として、ひととおりつかえることが大前提なので、

●STEP1
Wizardにでてくるものは、ひととおり、何もせずに(追加をね)、BUILDして実行してみる。
これです↓↓


●STEP2
『サンプル』として提供されてるものから、明らかに興味を引かないもの以外を、
BUILDして実行してみる、
これです↓↓


そこらへんを前準備としてやった後に、作りたいものを開始です。

私の場合は、最初に設計することをしません。
最後まで見通せるほど、普通の人間は、頭がよくないからです。

よく、SIerさんで、【要件定義】-【設計】-【詳細設計】-【実装】-
なんていうSTEPを、全て違う責任者がいたりして、
文書を書いてハンコをもらわないと進めなかったりして、
挙句の果てに、設計ミスがあっても戻れずに、
結果、ぐでぐでになるなんていうのは、
大きな企業ほどありがちです。
っていうか、あります。
っていうか、ありすぎます。

技術も流行りもめまぐるしくかわってる時代に、
いい年のおっちゃんがハンコを押したって、何もなりません。

まぁ結論から言えば、
設計書というのは、アプリが出来上がってから書くものなのです。

っと、話はそれましたが、
若い人には、
『常に美しい方法を選択し、感性でプログラムを書きながら、全体像を設計』
してほしいと思いますですね。
これでいいのです。
絵にすれば、こうです。(o^^o)










2014年6月27日金曜日

jajavascriptを再学習の7【配列メソッドを騙して使う件】

まぁ、サンプルと結果を先にだして見ましょう。
 

結果


いやいや、なかなかどうしてこういう結果なのです。
本によると、『配列メソッドを騙して使う』となってるのですが、
そんなに騙してるとも思えません。
Array.pushをArray.push.callとして呼び出し、
thisをObjectを指定しているというだけなので、
javascriptのArrayは、ArrayじゃなくてObjectでもOKという仕様
と言ってしまえばそれまでな気もします。。

本を読んだだけのときは、
lengthプロパティを追加してやらないと、
Array.push.callが失敗するのかと思いましたが、
設定しなくてもちゃんと動作します。(IE/CRM/FFX/OPR)

だから気分的には、こんな感じ(O^^O)


もっとわかりやすいサンプルとしては、こんな感じかな。。
配列にArray.pushした場合と、ObjectにArray.pushした場合。
 var abc = ["背負い投げ"];
 Array.prototype.push.call(abc,"出足払い");
 Array.prototype.push.call(abc,"横三角絞め");
 var def = {"得意技":"背負い投げ"};
 Array.prototype.push.call(def,"出足払い");
 Array.prototype.push.call(def,"横三角絞め");
 assertprop(abc,"abc");
 assert(true,"abc[0] = " + abc[0]);
 assert(true,"abc[1] = " + abc[1]);
 assert(true,"abc[2] = " + abc[2]);
 assertprop(def,"def");
 assert(true,"def[0] = " + def[0]);
 assert(true,"def[1] = " + def[1]);
 assert(true,"def[2] = " + def[2]);

2014年6月19日木曜日

jajavascriptを再学習の6【無名関数】と再帰

ということで、無名関数いきましょう。
 window.onload = function(){
  assert(true,"onload!!!");
 };

 var ninja = {
  seoi:function seoinage(){ assert(true,"ninja 背負い投げ!"); },
  ohsoto:function (){ assert(true,"ninja 大外刈り!"); }
 };
 ninja.出足払い = function(){ assert(true,"ninja 出足払い!");  };
 ninja.出足払い();
 ninja.seoi();
 ninja.ohsoto();
 assert(true,ninja.seoi.name);
 assert(true,ninja.ohsoto.name);
 assert(true,"------------END------------");
まぁこんな感じなわけですが。。

6行目7行目はそれぞれninjaObjectのプロパティとして関数を設定していますが、
前者は名前付き、後者は無名関数です。
それは、nameプロパティを表示させた結果(4)(5)を見ればわかるとおりです。

ただし、この【seoinage】という名前の関数、nameプロパティとして参照する外の用途
があるのかといわれれば、、ほとんどない。
なぜなら、関数の中からしか、この名前は参照できないからだ。
よって、再帰的に使う時には、その用途がある程度の話である。
(-_-;)

あと、現実的に使うかどうか別にして、
9、10行目と(1)の表示を見ればわかるとおり、日本語もOKっすね。

ということで、無名関数のサンプルで、こんなノリのやつが本にはかかれていたわけですが、
 var ninja = {
  chop:function (n){
   return (n>1)? ninja.chop(n-1) + "-chop" : "chop";
  }
 };
 assert(true,ninja.chop(4));
しかし、、まぁよくないサンプルとしてはいいのですが、、
プログラム的には、あまりに美しくないわけです。
せっかく【ninja】というobjectを定義(生成?)しておきながら、
そのプロパティとしての関数の中で、また【ninja】を参照するという。。。
本では、色々な使い方の中でよくない理由を述べてるのはいいのですが、、
いや、これ、それ以前の問題!くらいの認識を持たないとダメだよね。。
で、結論としてはもちろん、
 var ninja = {
  chop:function chopper(n){
   return (n>1)? chopper(n-1) + "-chopper" : "chopper";
  }
 };
 assert(true,ninja.chop(4));
そう、こういう風に関数に名前をつけましょうという話でした。
もちろん、arguments.calleeという話題も無いわけじゃないが、それはそれで。(o^^o)



2014年5月30日金曜日

jajavascriptを再学習の5【javascriptのthis】


javascriptのthisはよくわからないっすよねー。
なにかというと、
【callの第一引数に文字列Objectを設定可能】
なのですよね。

前回のサンプルによると、
function foreacher(list,callback){
 for(var w=0;w<list.length;w++){
  callback.call(list[w],w);
 }
}
var waza=["背負投","払腰","袖釣込腰","内股すかし","出足払い"];
foreacher(waza,
 function(idx){
  assert(this == waza[idx],waza[idx]);
 }
);
なんてことを書いてるわけですが。。
よくthisって何かって説明で、
【自分自身を表すObject】みたいに書いてあります。
まったくその通りなんですが、、、
サンプルを見てみると、、
waza[idx]は明らかに文字列です。
typeof(waza[idx]) は"string"です。
でも、this == waza[idx]はtrueです。
でも、this === waza[idx]はfalseです。
まぁここまではよしとしましょう。
しかしながら、以下はどうでしょう。
●その1
var moji = {};
moji.abc = function(){alert("moji-abc");};
moji.abc();
これを実行すると、alertが出ます。当然の結果です。でも、、、
●その2
var moji = "moji";
moji.abc = function(){alert("moji-abc");};//1
moji.abc();//2
これを実行すると、エラーです。
ためしに、typeof(moji.abc)を見ると、undefinedです。
でも、1ではエラーでにはなりません。
2がエラーになります。そんな関数しらないよと。
1のときに、【文字列Objectにプロパティをい追加できません】とか出してエラーになってくれるといいんですけどね。

このthisはサンプルのようには使えますが、だからといってその"waza[idx]"に、プロパティとか設定できません。
そう、なんの使い道があるのでしょう。
謎です。

2014年5月29日木曜日

javascriptを再学習の4【javascriptのthis】


javascriptのthisはよくわからないんですが、(という設定で^^;)
とりあえず、assert関係をちょっと拡張です。
●assert.css
function getProperties( object )
ul#resulter { border: 2px ridge maroon; background-color: #ccffcc; padding: 0.25em 1.5em; margin-left: 0; }
li.pass { color: #006400; font-weight:bolder;}
li.fail { color: #dc143c; text-decoration: line-through; font-weight:bolder;}
li.prop { color: #808000; font-weight:bolder;}
●assert.js
まぁ無駄は多いですが、気にせずに。
function getProperties( object )
{
    var ar = [];
    for( var pname in object ){
        var pvalue = object[ pname ];
        ar.push( pname + ' : ' + pvalue + "<" +  typeof(pvalue)  + ">" );
    }
    return  ar;
}
function assert(bbb, disp) {
 var resulter = document.getElementById("resulter");
 if (!resulter) {
  resulter = document.createElement('ul');
  document.getElementsByTagName('body')[0].appendChild(resulter);
  resulter.setAttribute('id','resulter');
 }
 var li = document.createElement("li");
 li.className = bbb ? "pass" : "fail";
 var disper = bbb ? "●" + disp : "×" + disp;
 li.appendChild(document.createTextNode(disper));
 resulter.appendChild(li);
}
function assertp( disp,bmem) {
 var resulter = document.getElementById("resulter");
 if (!resulter) {
  resulter = document.createElement('ul');
  document.getElementsByTagName('body')[0].appendChild(resulter);
  resulter.setAttribute('id','resulter');
 }
 var li = document.createElement("li");
 li.className = "prop";
 var disper = bmem ? "→" + disp : disp;
 li.appendChild(document.createTextNode(disper));
 resulter.appendChild(li);
}
function assertlist(list,name) {
 assertp( "------■" + name + "■------",false);
 for(var w=0;w<list.length;w++){
  assertp(list[w],true);
 }
 assertp( "--------------------");

}
function assertprop(o,name){
 if(name == undefined) name = "unknown";
 assertlist(getProperties( o ),name);
}
●つづく

2014年5月28日水曜日

javascriptを再学習の3【callとapply】

●まずはサンプルコードから
function ohsoto(){
 var result = 0;
 for(var w=0;w<arguments.length;w++){
  result += arguments[w];
 }
 this.result = result;
}
var n1 = {};
var n2 = {};
ohsoto(1,2,1);//1
assert(true,this.result);
ohsoto.apply(n1,[1,2,3,4,"five"]);//2
ohsoto.call(n2,1,2,3,4);//3
ohsoto.call(this,1,2,3);//4
assert(true,n1.result);
assert(true,n2.result);
assert(true,this.result);
●1のohsoto関数呼び出し。これはこのまま呼び出してるだけなので、普通の挙動です。
●2のapply。これはあとからn1がthisとして呼ばれていることがわかります。
●3のcall。これも2と同様、n2がthisとして呼ばれていることがわかります。
●4のcall。これは、Globalなthisで呼んでるのがわかります。
実はこれだけでは、thisを指定して呼べる以外、何の意味があるかわかりません。
でも、CALLBACKとかすると、初めてなんとなく意味がわかります。
とりあえず、結果は以下。

★では、callBackを使用したサンプルコード
function foreacher(list,callback){
 for(var w=0;w<list.length;w++){
  callback.call(list[w],w);
 }
}

var waza=["背負投","払腰","袖釣込腰","内股すかし","出足払い"];
foreacher(waza,
 function(idx){
  assert(this == waza[idx],waza[idx]);
 }
);

●うん。なんとなく使い方がわかってきた。
javascriptをjavascriptらしくかくと、たぶん、無名関数が続出する結果となる。(と思う(o^^o)
よって、無名関数内でのthisと変数スコープは重要。この件はまたそのうち。

しかし、よく見ると上記のサンプルは妙である。
【javascriptのthisってなんだかわけわからん】
ともいえる。
これは次回にしよう。。(o^^o)

2014年5月27日火曜日

javascriptを再学習の2【関数とObject】

ということで、実際には今回が最初になりますね。
今回のテーマは、【関数とobject】です。
これは、javascriptでは、
  function Nin(){
  }
というのがあったときに、
 Nin();
とすれば当然呼べます。関数ですから。 でも、
 var n1 = new Nin()
とかいても呼べます。
これは正確には、コンストラクタによる呼び出しらしいのですが、
あまり細かいことを気にせずいうと、【this】が違うということです。
だから、C++における、関数とクラスのメンバ関数の違いみたいなものです。
C++のクラスのメンバ関数は、中身としては通常の関数で、
その関数を呼ぶときの【this】が違うだけなのです。
ということで、テストコードを書いてみます。
  var a;
  function Nin(){
   a = this;
  }

  Nin();
  assert(true,a);

  var n1 = new Nin();
  assert(true,a);
  assert(a==n1,"a==n1みたいですよ!");
で、結果は以下。

最初がWindowということは、関数呼び出しの場合にはthisがGlobalということです。
newでの呼び出しは、なんかObjectが生成されて、そこがthisになってるってことですね。 とうぜんthisになってるので、ここでメソッドやプロパティを追加したりとかが自由ってことです。

ただ、とくに違和感があるかっていうと、私的には特にないです。
なにしろ、C++において、mallocした領域をクラスのポインタでキャストして、
newしないでクラスのインスタンスを生成したような使い方をしたりしてたので(o^^o)


2014年5月26日月曜日

javascriptを再学習の1

まずは、学習のために、assert関数と、CSSをつくります。
ほとんどパクリですんません。
●assert.js
function assert(bbb, disp) {
 var resulter = document.getElementById("resulter");
 if (!resulter) {
  resulter = document.createElement('ul');
  document.getElementsByTagName('body')[0].appendChild(resulter);
  resulter.setAttribute('id','resulter');
 }
 var li = document.createElement("li");
 li.className = bbb ? "pass" : "fail";
 var disper = bbb ? "●" + disp : "×" + disp;
 li.appendChild(document.createTextNode(disper));
 resulter.appendChild(li);
}
●assert.css
ul#resulter { border: 2px ridge maroon; background-color: #ccffcc; padding: 0.25em 1.5em; margin-left: 0; }
li.pass { color: #006400; font-weight:bolder;}
li.fail { color: #dc143c; text-decoration: line-through; font-weight:bolder;}
●sample

●結果

2014年5月22日木曜日

javascriptを再学習の0

jQueryのソースが読みきれなかったのキッカケに、javascriptを再学習。
学習したのは、基本的にこの一冊。
JavaScript Ninjaの極意
これが、稀に見る私にとっての良書と感じたので、
ここで学習したことをメモって、今一度理解を深めたいと思う次第。(o^^o)
向うの方は好きだよね。忍者とか。
笑えるのは、原書の表紙
でも、内容は秀逸です。



2013年3月1日金曜日

●このjavascript、iPhoneのサファリでフリーズ!

●このjavascript、iPhoneのサファリでフリーズ!
※name=uploadはfile。
$(function(){
    $('input[name=upload]').change(function() {
  var size = this.files[0].size;
  alert(size);
...略...

2013年2月28日木曜日

今さらながらJSONPath。(PHP)

なぜ今さらながらJSONPathかっていうと、どうにもいい感じにつかえるやつがなかったのです。
http://goessner.net/articles/JsonPath/
LastUpdateが2007年だけど^^;^^;
で、テストコードを書いてみると、ちょっとイイ感じです。
何がイイかって、resultTypeに"PATH"なるものが設定できるところで、この先頭の$を削除してObjectの変数名をつっこみ、
"黒魔術"のevalで、参照したり設定したり。
※javascriptの方も同様にできました。
●テストコード
 require_once "pear/Var_Dump.php";
 require_once "./jsonpath-0.8.1.php";

 $jstr = file_get_contents('samplejson.txt');
 $json = json_decode($jstr,true);

 $match1 = jsonPath($json, "$..author");
 $match2 = jsonPath($json, "$..author", array("resultType" => "PATH"));

 $res1 = Var_Dump::display($match1,true);
 $res2 = Var_Dump::display($match2,true);

 header( "Content-Type:text/html; charset=utf-8");

 $idxstr = $match2[1];
 $idxstr = "\x24json" . substr($idxstr,1);

 eval("\x24aa=" . $idxstr . ";");
 echo "->  {$aa} 
"; $idxstr .= "='A123456789';"; @eval($idxstr); // 失敗してもtry-catchで拾えません^^; $res3 = Var_Dump::display($json,true); echo "-> " . $idxstr . "
"; echo $res1; echo $res2; echo $res3; exit; /* samplejson.txtの中身。 { "store": { "book": [ { "category": "reference", "author": "Nigel Rees", "title": "Sayings of the Century", "price": 8.95 }, { "category": "fiction", "author": "Evelyn Waugh", "title": "Sword of Honour", "price": 12.99 }, { "category": "fiction", "author": "Herman Melville", "title": "Moby Dick", "isbn": "0-553-21311-3", "price": 8.99 }, { "category": "fiction", "author": "J. R. R. Tolkien", "title": "The Lord of the Rings", "isbn": "0-395-19395-8", "price": 22.99 } ], "bicycle": { "color": "red", "price": 19.95 } } } */ ?>
●表示結果
-> Evelyn Waugh 
-> $json['store']['book'][1]['author']='A123456789';
array(4) {
  0 => string(10) Nigel Rees
  1 => string(12) Evelyn Waugh
  2 => string(15) Herman Melville
  3 => string(16) J. R. R. Tolkien
}
array(4) {
  0 => string(31) $['store']['book'][0]['author']
  1 => string(31) $['store']['book'][1]['author']
  2 => string(31) $['store']['book'][2]['author']
  3 => string(31) $['store']['book'][3]['author']
}
array(1) {
  store => array(2) {
    book => array(4) {
      0 => array(4) {
        category => string(9) reference
        author => string(10) Nigel Rees
        title => string(22) Sayings of the Century
        price => float 8.95
      }
      1 => array(4) {
        category => string(7) fiction
        author => string(10) A123456789
...略...

iOS6未満でOperaMiniでFileUpload、やっぱりダメ

うぅーーん。やっぱり無理でした。
スマフォ用のWebサイトを、『どこまで対応端末としてターゲットにするか』
と言う問題はいつでもついてまわるわけですが、
jQuery+jQueryMobile+jQueryUpload &&
FileUpload de iPhone3G with OperaMini
  ↓
あえなく失敗。。。。^^;^^;
ファイル選択はできてるんですけどねー。。。
アプリにするしかないのか。。。。。

2012年5月29日火曜日

javascriptでJSONをPOSTしてみてPHPで受け取る。

前回のつづきで、javascriptでObjectを生成し、
それをJSON化し、それをPHPでPOSTで受け取るテストをしてみます。
テストとしては、どうやって文字列処理をすればいいのかってことですね。
また、javascriptからPOSTする方法も含めてテストしてみます。

ってことで、こんなコードでテスト


php
$a = Var_Dump::display($_POST,true);
echo $a;
で、結果は、、
------------------POST------------------
array(1) {
  param => string(77) {\"dat1\":\"【\'】【\\\"】【\\\\】【/】【\\r】【\\n】【\\t】\"}
}

ってことは、、、
{"dat1":【'】【\"】【\\】【/】【\r】【\n】【\t】}
が
{\"dat1\":\"【\'】【\\\"】【\\\\】【/】【\\r】【\\n】【\\t】\"}
になってるってことです。
じゃぁこれをどうやって取り込むかってことですね。
まぁJSONできてるから、JSONをdecodeできる文字列に変更する必要があるわけです。
まず、これはPHPの設定になるわけですが、文字のエンコードを調べます。
echo mb_detect_encoding($param);
ってやってみると、、
UTF-8
となりました。これが「UTF-8以外でいいことなんて、とりあえず何もありませんから、PHPは全てUTF-8前提で考えます。
ってことで、var_dumpでこういう結果↓をえるためには、
array(1) {
  dat1 => string(52) ◆【'】【"】【\】【/】【
】【
                     】【 】
}
PHP側で、こういう↓文字列処理をすればいいことになります。
$param = $_POST['param'];
$param = preg_replace("/\x5c\x5c\x22/",  "\x22",$param);  //【\"】 を 【"】 にする
$param = preg_replace("/\x5c\x5c\x27/",  "\x27",$param);  //【\'】 を 【'】 にする
$param = preg_replace("/\x5c\x5c\x5c\x5c/", "\x5c\x5c",$param); //【\\】 を 【\】 にする
もちろん、preg_replaceなので配列にして渡してもいいんですが、、、
そうやったからって言って、速度が速くなるわけでもないので(実験しました)、見やすいように3行にしました。

関数としてはたいしたことない関数。
 function objectFromJsJson($v){
  $vv = preg_replace("/\x5c\x5c\x22/",  "\x22",$v);  // 【\"】 を 【"】 にする
  $vv = preg_replace("/\x5c\x5c\x27/",  "\x27",$vv);  // 【\'】 を 【'】 にする
  $vv = preg_replace("/\x5c\x5c\x5c\x5c/", "\x5c\x5c",$vv); // 【\\】 を 【\】 にする
  $json = json_decode($vv,true);
  return $json;
 }

しかしここで、PHPでencodeすると、こんな文字列になります。
//【コード】
 $str = json_encode($json);
 echo $str;
//【結果】
{"dat1":"\u25c6\u3042\u3010'\u3011\u3010\"\u3011\u3010\\\u3011\u3010\/\u3011\u3010\r\u3011\u3010\n\u3011\u3010\t\u3011"}
日本語が\u表記になります。まぁ、文字のエンコードの問題があるので、この方が扱いやすいといわれればその通りかもしれません。

2012年5月25日金曜日

JSONのencode/decodeの注意な件。

現在、JSONを、以下の4言語で使用中なのですが、
エンコード関係のまとめを一度しなきゃいけないと思ってたので、
ちょっとまとめます。
もちろん、ASとJSは、基本的にはECMAスクリプトですが、
使うライブラリの問題もしれないので、分けます。

(1)C++ → 自前処理
(2)php → json_decode/json_encode関数
(3)ActionScript → com.adobe.serialization.json.JSONにおける、encode,decode
(4)javascript → JSON.stringify/JSON.parse関数(evalは使わない)

ということで、C++の場合は、自分でやってるので、特に言及しません。

問題になりそうなのは、主に、記号類。
その中でも、
【/】【\】【'】【"】【改行】
が重要だと思うので、これらをそれぞれで入力したとき、JSONに変換したとき、POSTで受け取るときなどをまとめてみます。

●テスト1
javascriptでオブジェクトを生成して、それをJSON文字列化。


01.html

結果
で、最後の16進コードをもとに見てみると、
【’】【¥”】【¥¥】【/】【¥r】【¥n】【¥t】
である。(全角表示)
ようするに、【’】と【/】は、escapeされない。まぁそういぅ仕様だわね。。
まぁ、あたりまえの事を、一応やってみて確認することが重要なのです。
なんで、16進コードなんかで見るかっていうと、
こんな簡単なコードでも、ブラウザによってalertの表示が違うんですよね。TABとか¥rとかね。 こんな簡単な例だと間違えないけど、javascriptを動的に文字列で作り出したりしてるときに気を抜いていると、思わぬことになるのです。