javascriptのselfとthisは結び目を使います.

10260 ワード

一、selfこれはとても簡単です.私達は知っていて、どのウェブページを開けても、ブラウザはまず一つのウィンドウを作成します.このウィンドウは一つのwindowオブジェクトであり、js実行に依存するグローバル環境オブジェクトとグローバルスコープオブジェクトです.selfとは、ウィンドウ自体を指し、オブジェクトはwindowオブジェクトと同じです.そのため、windowオブジェクトの一般的な方法と関数は、windowの代わりにselfを使用することができます.例を挙げると、よくある書き方は「self.close()」のようにマーク中:" ウィンドウを閉じるに置いて、「ウィンドウを閉じる」リンクをクリックして、現在のページが閉じられています.二、thisキーワードはthisを話す前に、次のコードを見てください.


function thisTest()
  {
      this.textValue = 'this dom  ';
      this.element= document.createElement('span');
      this.element.innerHTML = this.textValue;
      this.element.style.color = "blue";
      this.element.style.cursor = "pointer";
      this.element.attachEvent('onclick', this.ToString);
  }
   
  thisTest.prototype.RenderDom = function()
  {
      document.body.appendChild(this.element);
  }     

  thisTest.prototype.ToString = function()
  {
      alert("   :"+this.textValue);
  };
  var test= new thisTest();
  test.RenderDom(); 
  //test.ToString();


本来の目的は、bodyにspan要素を追加したいということです.このspan元素に対して、フォント色を制定し、その上に浮遊するマウススタイルとクリックトリガーイベントです.問題はそのクリックイベントに現れます.ある人はあなたがまたばかだと言うかも知れなくて、こんなに多くのsbコードを書いてまだ下のこの東を実現するためではありませんか?
this dom  
どのように簡単で直感的で、間違えにくいですか?カオ、目まいがします.今話しているのはあなたが使っているthis.inners HTMLの中のthisです.1、thisとは何ですか?私たちがよく知っているccaにはthisというキーワードがありますが、その主な役割は現在のオブジェクトの例(パラメータ伝達とインデックスの両方にthisを使用します)を指します.javascriptでは、thisは通常、私たちが実行している関数そのもの、またはその関数が属するオブジェクト(実行時)を指します.2、よくある使い方(1)、直接domの中で使う

解析:dom元素の一つのonclick(または他のonblurなど)の属性に対して、それは所属するhtml元素のために持っていて、直接に触発する関数の中でthisを書いて、thisはこのhtml元素を指すべきです.(2)、dom元素にjs関数aを登録し、不正な方式

  function thisTest(){
  alert(this.value); //   undefined, this     ??
}



解析:onclickイベントは直接thisTest関数を呼び出して、プログラムはundefinedを弾きます.thisTest関数はwindowオブジェクトで定義されているので、thisTestの所有者はwindowであり、thisTestのthisもwindowである.windowはvalue属性がないので、間違えました.b、正しい方式



  function thisTest(){
  alert(this.value); 
}
document.getElementById("btnTest").onclick=thisTest; // button onclick        

解析:前の例では、thisTest関数はグローバルスコープ(ここではwindowオブジェクト)で定義されているので、thisは現在のwindowオブジェクトを指す.Dcument.getElementById(「btnTest」)を通じて.onclick=thisTest;このような形では、btnTestのonclick属性をthisTest関数のコピーとして設定し、btnTestのonclick属性の関数作用領域内では、thisはbtnTestに属し、thisはbtnTestを指している.もし複数のdom要素が登録されているなら、私たちは異なるdom元素idを利用して、以下のように実現できます.document.getElementById(「domID」).onclick=thisTest;/buttonのonclickイベントに関数を登録します.複数の異なるHTML要素が異なる関数コピーを作成しているが、各コピーの所有者は対応するHTML要素であり、それぞれのthisもそれらの所有者を指しており、混乱を招くことはない.上記の説明を検証するために、私達はコードを改善して、ブットンに直接にそれらの対応するトリガ関数をイジェクトさせます.




function thisTest(){
this.value="   ";
}
var btn=document.getElementById("btnTest1");
alert(btn.onclick); //       

var btnOther=document.getElementById("btnTest2");
btnOther.onclick=thisTest;
alert(btnOther.onclick); //       

そのポップアップの結果は、
//     
function onclick(){
  thisTest()
}
 
//     
function thisTest(){
  this.value="   ";
}
上の結果からあなたはきっとよく分かります.By the wayは、新しい関数のコピーを作成するごとに、この関数のコピーにメモリを割り当てます.実際のアプリケーションでは、ほとんどの関数が呼び出されるとは限らないので、この部分のメモリは無駄にされてしまいます.だから私たちは通常こう書きます.






  function thisTest(obj){
  alert(obj.value); 
}

これは関数参照の方式を使うと、プログラムは関数の本体にメモリを割り当てるだけで、参照はポインタだけを割り当てるからです.このように関数を書いて、呼び出したところに引用を割り当てると、効率が高くなります.もちろん、このような登録イベントは複数のブラウザに対応できないと思ったら、以下の登録イベントの共通シナリオを書くことができます.
//js      EventUtil.addEvent(dom  ,    ,        )   EventUtil.removeEvent(dom  ,    ,        )
var EventUtil = new eventManager();

//js        dom           
function eventManager() {
    //    
    //oDomElement:dom  ,   ,  ,document ; ****** oEventType:    ( :click,   ie   ,   click   onclick);****** oFunc:        
    this.addEvent = function(oDomElement, oEventType, oFunc) {
        //ie
        if (oDomElement.attachEvent) {
            oDomElement.attachEvent("on" + oEventType, oFunc);
        }
        //ff,opera,safari 
        else if (oDomElement.addEventListener) {
            oDomElement.addEventListener(oEventType, oFunc, false);
        }
        //  
        else {
            oDomElement["on" + oEventType] = oFunc;
        }
    }

    this.removeEvent = function(oDomElement, oEventType, oFunc) {
        //ie
        if (oDomElement.detachEvent) {
            oDomElement.detachEvent("on" + oEventType, oFunc);
        }
        //ff,opera,safari 
        else if (oDomElement.removeEventListener) {
            oDomElement.removeEventListener(oEventType, oFunc, false);
        }
        //  
        else {
            oDomElement["on" + oEventType] = null;
        }
    }
}
コメントのように、dom要素イベントを登録するには、EventUtil.addEvent(dom元素、イベント名、イベントトリガの関数名)を使って、削除するときに、EventUtil.removeEveveveEvent(dom元素、イベント名、イベントトリガの関数名)と書きます.これは余談です.もう言いません.(3)、クラス定義ではthisキーワードを使うのが一般的ですが、例を見てください.
function thisTest()
  {
      var tmpName = 'jeff wong';
      this.userName= 'jeff wong';
  }

var test= new thisTest();
alert(test.userName==test.tmpName);//false
alert(test.userName); //jeff wong
alert(test.tmpName); //undefined
この結果を分析してみると、実はここのthisとczhiの中のものは似ています.(4)脚本の対象に原形を付ける方法はここを理解する前提として、jsのプロトタイプ概念を理解しなければなりません(ここで言うと、kaoは本当に面壁が必要です):jsの対象のプロトタイプの属性は、対象タイプの原型に戻るための参照です.すべてのjsの内部オブジェクトにはリードオンリーのprototype属性があり、そのプロトタイプには動的に機能(属性と方法)を追加することができますが、このオブジェクトは異なるプロトタイプを付与することができません.しかし、ユーザによって定義されたオブジェクトは、新しいプロトタイプに割り当てられ得る.簡単な例を見てください.
//js     String,           (     )
//            
String.prototype.Trim = function() {
    return this.replace(/(^\s+)|(\s+$)/g, "");
}

function thisTest()
  {
      var tmpName = 'jeff wong';
      this.userName= '      jeff wong  ';
  }
//              
thisTest.prototype.ToString = function()
  {
      alert(this.userName); //jeff wong(*   *)
      alert(this.userName.Trim()); //jeff wong (*   *)
      //alert(tmpName); //    ,tmpName   
  }

var test= new thisTest();
test.ToString(); //     ToString()

function myTest(){
  this.userName= '  test ';
}
var test1=new myTest();
//test1.ToString(); //         ToString()  

//              
myTest.prototype = new thisTest();
test1.ToString(); //     ToString()
テスト結果によると、ここでのthisは、原形(方法または属性)を追加したクラスの例を指し、(3)の定義とほぼ同じである.(5)関数の内部関数でthisのキーワードを使っています.これを理解すると、ロールエリアとクローズドが分かります.問題は解決されます.最も典型的な例を見ると、
function thisTest()
  {
      this.userName= 'outer userName';
      function innerThisTest(){
        var userName="inner userName";
        alert(userName); //inner userName
        alert(this.userName); //outer userName
      }
     return innerThisTest;
  }

thisTest()();
分析:thisTest()内部のinners Test関数を呼び出して、一つのクローズドを形成する.innerThisTest実行時にinnerUserNameが最初にイジェクトされたのは、innerThisTest関数のスコープ内にuserNameという変数があるので、現在のスコープ下の変数の指定値を直接イジェクトしたからです.第2のポップアップouter userNameは、innerThisTestの役割領域にuserName属性がないためであり(例ではthis.userName)、前のロールエリアにuserName属性を探して、今回はthisTestで見つけられた(例ではthis.userName='outer uster Name')、対応するポップアップ値である.(6)Functionのcallとapply関数で特定のthisという指定を指定して指定すると、thisは「私がいて、あなたがいます.あなたがいます.」という状況になる可能性があります.自分を気絶させたくないなら、了解してください.this指定のオブジェクトを変更することは、コードのメンテナンスにも良くないことです.前の文の例のコードを貼り付けて終了します.
function myFuncOne() {
    this.p = "myFuncOne-";
    this.A = function(arg) {
        alert(this.p + arg);
    }
}

function myFuncTwo() {
    this.p = "myFuncTwo-";
    this.B = function(arg) {
        alert(this.p + arg);
    }
}
function test() {
    var obj1 = new myFuncOne();
    var obj2 = new myFuncTwo();
    obj1.A("testA");                       //  myFuncOne-testA 
    obj2.B("testB");                        //  myFuncTwo-testB 
    obj1.A.apply(obj2, ["testA"]);          //  myFuncTwo-testA,  [ testA”]          
    obj2.B.apply(obj1, ["testB"]);          //  myFuncOne-testB,  [ testB”]          
    obj1.A.call(obj2, "testA");             //  myFuncTwo-testA 
    obj2.B.call(obj1, "testB");             //  myFuncOne-testB 
}
まとめ:ここでは、冒頭のspanでundefinedが飛び出す問題について、あなたはすでに開豁していますか?今のこのspan元素はtextValue属性がありますか?三、void 1、javascriptにおけるvoidを定義するオペレータであり、このオペレータは、式を計算するが、値を返さないことを指定する.2、構文void操作子の使い方は以下の通りです.(1).javascript:void(expression)(2).javascript:void expressition注意:expressionは計算するjs標準的な表現です.表式の外側の括弧は任意ですが、括弧内の表現が一目で分かります.3、インスタンスコード
        function voidTest() {

            void (alert("it is a void test")); //    

            var oTestNum = 1;
            void (oTestNum++); //    
            alert(oTestNum);

            oTestNum = 1;
            void (oTestNum += " void test"); //      
            alert(oTestNum);
        }
        voidTest();
4、a元素の下でvoid(0)(1)を使う場合、ウェブページの中で、私達はよく見ています.htmlの中のaタグはあるページにナビゲートする必要がない場合、href属性の設定の書き方:
    link 1
    link 2
注意:第一の種類の「〓」の書き方(実際には、A元素があるリンクは、ブラウザの画面の下にあると、ページが上にスクロールすることになります.ですから、aラベルが必要です.他のページにナビゲーションしないでください.ページの位置のロールバックはいらないです.void(0)という書き方をします.(2)ie 6下void(0)による怪しい問題についてネット上で多くの議論があり、個人的には「落ち葉が長沙に満ちている」という表現が代表的だと思いますが、ここでは詳しく説明しません.
本論文は抜き書きであるhttp://www.cnblogs.com