0

私は今これに数回遭遇しました。私はそれを示すことができる最も単純なコードスニペットを作成しようとしました。

問題は、オブジェクトメソッド内で、匿名関数をjQueryメソッド(「each」など)に渡すと、関数内でオブジェクトの「this」にアクセスできなくなることです。「this」はjQueryオブジェクトに関連しているためです。

logNameAndElementIds問題の核心については、メソッドの途中にあるコメントを参照してください。

(私はCrockfordのオブジェクト関数を使用して、オブジェクトリテラルで定義されたオブジェクトに基づいてオブジェクトインスタンスを生成しています。)

Object.create = function (o) {
    function F() {}
    F.prototype = o;
    return new F();
};


var objectLiteral = {

    setName: function(name){
        this.name = name;
    },

    logNameAndElementIds: function(){

        // works fine, 'this' refers to object instance
        console.log( this.name );

        $('.foo').each(function(){

             // we've lost "this" because it now refers to jQuery
            console.log( this.name ); 
            console.log( $(this).attr('id') );
        });
    }

};

obj1 = Object.create(objectLiteral);
obj1.setName('Mike');
obj1.logNameAndElementIds();

この種の状況を処理または回避する正しい方法は何ですか?

明らかに私の例は愚かですが、それは単に要点を示すためのものです。多くの場合、jQueryに一致するセットをループしてから、各アイテムに含まれるオブジェクトのメソッドを呼び出します。しかし、jQueryの「this」があるため、オブジェクトのメソッドにアクセスできません。

4

4 に答える 4

1

この問題を回避する方法はthis、新しいスコープ内でアクセスできる変数に保存することです。

logNameAndElementIds関数を見てください:

logNameAndElementIds: function(){

    // works fine, 'this' refers to object instance
    console.log( this.name );
    var that = this;

    $('.foo').each(function(){

        // we've lost "this" because it now refers to jQuery
        console.log( that.name ); 
        console.log( $(this).attr('id') );
    });
}
于 2012-08-16T17:31:47.003 に答える
0

これには、以前に受け入れたものよりも良い答えがあると思います。それは、ES5の新しいFunction.prototype.bindメソッドを使用することです。はるかにクリーンで、最新のすべてのブラウザーで使用でき、古いブラウザーでは簡単にシムできます。

bind()を使用すると、次のようなことができます。

var myObj = {
    name: "Foo";

    iterateParagraphs: function() {
        $("p").each(function(i,p){
            $(p).addClass("bar"); // use $(p) where you use to use $(this);
            $(p).text(this.name); // this refers to myObj = Foo
        }.bind(this)); // get this (myObj) into callback
    }
};

Mozillaシムの縮小版(これは最高のようです)は次のとおりです。

Function.prototype.bind||(Function.prototype.bind=function(b){if("function"!==typeof this)throw new TypeError("Function.prototype.bind - what is trying to be bound is not callable");var d=Array.prototype.slice.call(arguments,1),e=this,a=function(){},c=function(){return e.apply(this instanceof a&&b?this:b,d.concat(Array.prototype.slice.call(arguments)))};a.prototype=this.prototype;c.prototype=new a;return c});
于 2012-10-04T12:07:00.003 に答える
0

'pointer'の値はthis、機能ブロックのスコープに応じて変化します。this外部スコープからを参照するには、元のオブジェクトのコピーを保存しますthis(一般的な規則では、次のように保存しますself)。

var objectLiteral = {

    setName: function(name){
        this.name = name;
    },

    logNameAndElementIds: function(){

        // works fine, 'this' refers to object instance
        console.log( this.name );

        var self = this;

        $('.foo').each(function(){

            //use 'self' instead of 'this'

            console.log( self.name ); 
            console.log( $(this).attr('id') );
        });
    }

};
于 2012-08-16T17:31:27.850 に答える
0

これは既知のことです。通常、元のプロキシを使用しますthis

    var that = this;
    $('.foo').each(function(){

        console.log( that ); // original object
        console.log( this ); 


    });
于 2012-08-16T17:31:29.967 に答える