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)
向うの方は好きだよね。忍者とか。
笑えるのは、原書の表紙
でも、内容は秀逸です。