15

この「オブジェクト」内の「これ」を失う発行者がいます。次のJavaScriptの出力は、「some-id」、「undefined」の順になります。コールバック関数内で「this」を使用すると、スコープがオブジェクトの外に出て、「this」を使用できなくなります。'this'を使用するようにコールバックを取得する、または少なくともオブジェクトにアクセスするにはどうすればよいですか?

複数のオブジェクトを作成するため、ストレージのような「静的」を作成することはできません。このjavascriptn00bを助けてください;-)

これが私の問題を再現するために使用できる私のテストコードです。私が欲しいのは、このテストケースに一致するはずCheckBox.doSomething()の値を返すことです。this.idsome-id

function CheckBox(input_id) {
    this.id = input_id;
    this.doSomething();
    $('#some-element').click(this.doSomething);
}

Checkbox.prototype.doSomething = function() {
    alert(this.input_id);
}

var some_box = new CheckBox('some-id');
some_box.doSomething();
$('#some-element').click();

編集:私はこれを私が望むように動作させることさえできません:

function CheckBox2(input_id) {
    this.id = input_id;
    alert(this.id);
}

CheckBox2.prototype.doSomething = function() {
    alert(this.input_id);
}
var some_box = new CheckBox2('some-id');
some_box.doSomething();
4

3 に答える 3

18

あなたの問題はこの行にあります:$('#some-element').click(this.doSomething);

なぜこれが問題なのか

JavaScriptメソッドは、割り当てられるべきオブジェクトについて何も知りません。thisメソッドが明示的に(with myFunction.call(obj))または暗黙的に(usingを使用して呼び出された場合)呼び出されたときに設定されますobj.myFunction()

例えば:

var x = {
    logThis: function () {
        console.log(this);
    }
};

x.logThis(); // logs x
x.logThis.call(y); // logs y

var func = x.logThis;
func(); // logs window: the fallback for when no value is given for `this`

あなたの場合、this.doSomethingjQueryに渡しており、jQueryは、クリックされた要素を値として明示的に呼び出していますthis。何が起こっているのか(少し複雑なバージョン)は次のとおりです。

var callback = this.doSomething;
callback.call(anElement, anEvent);

ソリューション

doSomethingが正しい値で呼び出されていることを確認する必要がありthisます。別の関数でラップすることでそれを行うことができます:

var cb = this;
$('#some-element').click(function() {
    return cb.doSomething();
});

jQueryは、proxyこれをより簡単に実行できる関数を提供します。

$('#some-element').click(jQuery.proxy(this.doSomething, this));
于 2012-05-26T13:24:14.680 に答える
11
function CheckBox(input_id) {
    this.id = input_id;
    this.doSomething = $.proxy( this.doSomething, this );
    $('#some-element').click(this.doSomething);
}

これに相当する「javascript」はFunction#bind、すべてのブラウザで使用できるわけではありません。jQueryを使用しているように見えるため、jQueryに相当するものを使用しています。$.proxy

于 2012-05-26T12:57:02.290 に答える
3

他の人はすでに問題の原因とjQueryでそれを修正する方法を説明しています。残っているのは、標準のJavaScriptで修正する方法です。それ以外の ...

$('#some-element').click(this.doSomething);

... あなたが書く:

document.getElementById('some-element').addEventListener('click', this.doSomething.bind(this));

thisこれにより、内部のコンテキストが変更されdoSomethingます。また、匿名関数を使用してそれを行うこともできます-代わりに...

$('#some-element').click(function(event) {
    console.log(this);
});

... あなたが書く:

document.getElementById('#some-element').addEventListener('click', (function(event) {
    console.log(this);
}).bind(this));

これは、Node.js(古いブラウザーを気にする必要がない)など、コールバックが多いプロジェクトで非常に役立ちました。

編集:getElementById()そしてaddEventListener()の代わりに$(...).click(...)

于 2014-07-04T08:31:07.653 に答える