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 shim 的缩小版本(这似乎是最好的)是:

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

“指针”的值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 回答