2012-03-07 37 views

答えて

9

内部にという関数があると便利です。そのような入れ子関数内のコードは、外部コンテキストからthisの値にアクセスする必要があります。 thisは、すべての関数呼び出しのために新たに確立されているので

function example() { 
    var me = this; 
    document.getElementById('whatever').onclick = function() { 
    me.clicked = 1; 
    }; 
} 

は、変数に外側thisをスタッシュすることなく、内側の関数から全くそれを参照する方法がないと思います。

+0

ありがとう! – ilija139

4

thisへの参照を保存するために使用します。コードの後半にはコールバック付きのAJAX呼び出し(たとえば)があります。したがって、そのコールバックの中でthisは外部と同じではありません。だからこそ人々は "外側" thisを変数にバックアップしています。

私は個人的にこのフォームを使用したい:

var that = this; 

は、ちなみに

:)おかしいCoffeeScript、「右行われたJavaScript」の一種である、このための修正プログラムがありますよく

これには、機能定義、薄い矢印と太い矢印の2つの形式があります。細い矢印はjavascriptとまったく同じように動作し、太い矢印は自動的にthisを外部コンテキストの値にバインドします。だから、

、このCoffeeScriptの

Account = (customer, cart) -> # thin arrow 
    @customer = customer 
    @cart = cart 

    $('.shopping_cart').bind 'click', (event) => # fat arrow 
    @customer.purchase @cart 

はこのJavaScript

var Account; 
Account = function(customer, cart) { 
    var _this = this; 
    this.customer = customer; 
    this.cart = cart; 
    return $('.shopping_cart').bind('click', function(event) { 
    return _this.customer.purchase(_this.cart); 
    }); 
}; 

クールに変換します、そうではありませんか?

1

thisが変更された場合でも、必要なコードにはthisという参照が残っています。

1

IMOそれはあなた自身がそれを見るのは珍しいことです。それは、実行中に評価された宣言ではなく、this値のJSの処理を避けるためにクロージャが関与するときにほぼ常に使用されるコンストラクトです。

1

コールバックが実行されるときにスコープが異なるコールバックメソッドによく使用されます。

例:

var me = this; 
$.getJSON(url, function(data) { 
    // here "this" will be "window", so "me" is used to access the object 
}) 
0

閉鎖スコープのためのものです。これらの2つのjQueryプラグインの違いを見てください。

$.fn.blinkClosure = function() { 
    var jQueryMonad = this, toggleClass = this.toggleClass; 
    setInterval(function() { 
     toggleClass.apply(jQueryMonad, ['invisible']); 
    }, 500); 
}; 

問題はsetIntervalです。 setIntervalの関数が呼び出されると、新しいチェーンが実行され、そのチェーン内のthiswindowにバインドされます。クロージャの例では、プラグインを適用するjQueryオブジェクトへの参照をjQueryMonad(またはコードのme)に保存しています。このようにして、javascriptで範囲を正しく維持することができます。

$.fn.blink = function() { 
    setInterval($.proxy(function() { 
     this.toggleClass('invisible'); 
    }, this), 500); 
}; 

第2の例では、jQuery.proxyがそれを処理します。

これは、javacriptが作成時に実行時にthisをバインドするときの問題を解決するためです。

1

通常の理由は、コードに後で呼び出されるクロージャが含まれており、クロージャが現在のthisにアクセスできるようにしたいということです。例:

は、ここの人々は頻繁にこのように、間違って記述したコードです:

var obj = { 
    name: "Fred", 
    foo: function() { 
     setTimeout(function() { 
      alert(this.name); // <=== Fails, `this` is no longer `obj` 
     }, 1000); 
    } 
}; 
obj.foo(); 

はここvar me = this;がそれに適用されていることです:

var obj = { 
    name: "Fred", 
    foo: function() { 
     var me = this; 
     setTimeout(function() { 
      alert(me.name); // <=== Works now 
     }, 1000); 
    } 
}; 
obj.foo(); 

JavaScriptで、thisがによって完全に定義されているので、これは、約来てファンクションが定義されている場所ではなく、ファンクションがと呼ばれています。これは、内側の関数で使用される

0

もっと読み(開示:両方は私のブログへのリンクです)。ご存じのように、オブジェクトコンストラクタに関数を持たせることができ、関数内に関数が存在することがあります。下のコードが表示されている場合。

function Circle(radius){ 
this.radius=radius; 
this.getArea=function(){ 
        var changeRadius=function(){ 
          this.radius=20; //here this points to global 
         } 
        changeRadius(); 
        return Math.PI*Math.pow(this.radius, 2); 
        } 
} 

var cd= new Circle(10); 
console.log(cd.getArea()); 

はあなたのgetArea()を呼び出すと、あなたはchangeRadius()が、内部機能changeRadius内を呼び出しているが、これは代わりに、作成したオブジェクトのグローバルオブジェクトを指すように開始し、半径10に従って面積を取得します。ここでは、var self=this constructを使用します。

この状況を回避するために、以下の変更を加えることができます。

function Circle(radius){ 
var self=this; 
this.radius=radius; 
this.getArea=function(){ 
        var changeRadius=function(){ 
          self.radius=20; 
         } 
        changeRadius(); 
        return Math.PI*Math.pow(this.radius, 2); 
        } 
} 

var cd= new Circle(10); 
console.log(cd.getArea()); 
関連する問題