JS对象this.method()通过jQuery打破(JS Object this.method(

2019-07-21 18:26发布

我敢肯定有一个简单的答案,但它是星期五下午,我累了。 :(

不知道怎么解释呢,所以我就继续和发布示例代码...


下面是一个简单的对象:

var Bob =

{ Stuff : ''

, init : function()
    {
        this.Stuff = arguments[0]
    }

, doSomething : function()
    {
        console.log( this.Stuff );
    }

}

在这里,它被用于:

$j = jQuery.noConflict();
$j(document).ready( init );


function init()
{
    Bob.init('hello');

    Bob.doSomething();

    $j('#MyButton').click( Bob.doSomething );
}

一切正常,除了最后一行。 当jQuery的调用DoSomething的方法,这是压倒一切的“本”,并从工作停止它。

尝试使用刚刚Stuff也不行。

所以,我怎么是指对象的自身属性的方式,可以让jQuery来调用它,也允许对象与调用jQuery对象工作?

即我希望能够做这样的事情:

doSomething : function()
    {
        console.log( <CurrentObject>.Stuff + $j(<CallerElement>).attr('id') );
    }

(这里<CurrentObject><CallerElement>被替换为适当的名称。)

Answer 1:

的身份this是在JavaScript中一个常见的问题。 这也将打破,如果你想创建一个快捷方式doSomething

var do = Bob.doSomething;
do(); // this is no longer pointing to Bob!

它不依赖于身份良好实践this 。 你可以在多种方式,但最简单的就是明确地引用Bob而不是this里面doSomething 。 另一种是用一个构造函数(但你失去了冷静对象的文字语法):

var createBob = function() {
    var that = {};

    that.Stuff = '';
    that.init = function() {
        that.Stuff = arguments[0];
    };

   that.doSomething = function() {
       console.log( that.Stuff );
   };

   return that;   
}

var bob = createBob();


Answer 2:

这不是jQuery的错,这是不可或缺的JavaScript的处理对象的方式。

不像大多数其它面向对象的语言中,“这个” 绑定在每个方法级在JavaScript; 相反,它是由函数如何调用纯粹是确定的:

Bob= {
    toString: function() { return 'Bob!'; },

    foo: function() { alert(this); }
};
Brian= {
    toString: function() { return 'Brian!'; },
};

Bob.foo(); // Bob!
Bob['foo'](); // Bob!

Brian.foo= Bob.foo;
Brian.foo(); // Brian! NOT Bob

var fn= Bob.foo;
fn(); // window NOT Bob

你正在做的情况下,是什么:

$j('#MyButton').click( Bob.doSomething );

就像是与最后一个例子fn :你是拉功能doSomething关鲍勃并将它传递给jQuery的事件处理程序二传手作为一个纯函数:它不再有鲍勃或任何其他对象的任何连接,这样的JavaScript通过在全球window对象代替。 (这是JavaScript的最糟糕的设计特点之一,因为您可能不会立即注意到window是不是Bob ,并开始其访问属性,导致怪异和混乱的相互作用和错误。)

要记住的鲍勃,你通常做一个功能在nickyt的回答,让“鲍勃”的副本封闭,因此它可以在回调时被记住和用来调用真正的方法。 但是现在有这样做,在ECMAScript中第五版标准的方式:

$j('#MyButton').click( Bob.doSomething.bind(Bob) );

(你也可以把额外的参数在bind电话拨打doSomething回他们,这是很方便的。)

对于那些还不支持第五版的bind()方法本身(其中,在这一点上,是大多数)的浏览器,你可以在自己的执行黑客bind (Prototype库也做到这一点),这样的:

if (!Object.bind) {
    Function.prototype.bind= function(owner) {
        var that= this;
        var args= Array.prototype.slice.call(arguments, 1);
        return function() {
            return that.apply(owner,
                args.length===0? arguments : arguments.length===0? args :
                args.concat(Array.prototype.slice.call(arguments, 0))
            );
        };
    };
}


Answer 3:

更改

$('#MyButton').click( Bob.doSomething );

$('#MyButton').click( function() { Bob.doSomething() } );

你也可以添加到您的鲍勃反对私人领域的var that = this和使用无处不在的成员,而不是this ,如果你真的想避免匿名函数。

var Bob = new function() {
    // Private Fields
    var that = this;

    // Public Members   
    this.Stuff = '';

    this.init = function() {
                that.Stuff = arguments[0];
        }

    this.doSomething = function() {
                console.log( that.Stuff );
        }
}


Answer 4:

你总是可以尝试做这样的事情:

$j('#MyButton').click(function(event) {
  Bob.doSomething(event, this);
});

现在, doSomething仍会有Bobthis ,并利用函数的参数,这将有event的对象,它被触发的元素。



文章来源: JS Object this.method() breaks via jQuery