简体   繁体   English

JavaScript对象中的“ this”与jQuery $(this)

[英]“this” in JavaScript objects vs. jQuery $(this)

I've stumbled over a problem. 我偶然发现了一个问题。 I have an object method foo defined as: 我有一个对象方法foo定义为:

var obj = {
    foo: function() {
        $('.personName').mouseover(function() {
            this.highlight($(this).attr('faceIndex'));
        });
    }
}

So what should happen is that whenever the mouse cursor is over an HTML object of type personName , the obj.highlight method should be called with the faceIndex value from the HTML object as an argument. 因此,应该发生的情况是,每当鼠标光标位于personName类型的HTML对象上时, personName使用HTML对象中的faceIndex值作为参数来调用obj.highlight方法。 However I apparently have a clash between two this's: the one of jQuery and the one of JavaScript (referencing to obj from inside obj ). 但是我显然有冲突,这两者之间是:jQuery的的一个和JavaScript的一个(引用到obj从内obj )。

What can (should) I do? 我能(应该)做什么? Have I violated some good programming practice? 我违反了一些良好的编程习惯吗?

A typical pattern to work around this is to use a local variable to store the first this : 解决此问题的典型模式是使用局部变量存储第一个this

var obj = {
    foo: function() {
        var _this = this;
        $('.personName').mouseover(function() {
            _this.highlight($(this).attr('faceIndex'));
        });
    }
}

Using a language like TypeScript or an ES6 compiler makes it easier to use this pattern without having to write the _this by hand each time. 使用TypeScript之类的语言或ES6编译器可以更轻松地使用此模式,而不必每次都手动编写_this

Short answer: do 简短答案:

    $('.personName').mouseover(function(event) {
        obj.highlight($(event.target).attr('faceIndex'));
    });

Longer explanation: 更长的解释:

Javascript doesn't really have a concept of this . JavaScript并没有真正的概念this At least not in the way you're used to thinking of it. 至少不会像以前那样思考它。 Oh there's a keyword alright, and it kind of does the thing you expect a lot of the times but it doesn't work the way that you probably think. 哦,这里有一个很好的关键字,它在很多时候都可以满足您的期望,但是它并不能像您想象的那样起作用。

The fact of the matter is that in javascipt, this is no different than any other parameter. 事实是,在javascipt中, this与任何其他参数没有什么不同。 Let me show you. 让我演示给你看。

Most people are aware that in javascript you can invoke functions like this doSomething(param1, param2) or like this doSomething.call(null, param1, param2) . 大多数人都知道,在javascript中,您可以调用类似doSomething(param1, param2)或类似doSomething.call(null, param1, param2)函数。 If you wanted, you can write all function invocations using .call 如果需要,可以使用.call编写所有函数调用

See that null there? 看到那null吗? Anything you pass in there is what this gets set to. 你在那里通过什么就是this被设置为。

doSomething.call(null, param1, param2);
doSomething.call(obj, param1, param2);
doSomething.call(window, param1, param2);
doSomething.call("foobar", param1, param2);

If you don't use .call the runtime just takes a guess at what value you want there. 如果您不使用.call则运行时仅猜测您想要的值。

So given this, consider that the only difference between this and any other parameter is that you don't get to give this a name! 因此,考虑到这一点,请考虑this参数与任何其他参数之间的唯一区别是不要给this一个名字! Your problem is that you have two function scopes and the inner one has a variable named this which hides the outer one's this . 您的问题是您有两个函数作用域,而内部作用域具有一个名为this的变量, this变量隐藏了外部作用域的this

Solution: don't use this . 解决方案:不要使用this Most libraries in fact (jquery included), don't force you to use this and also pass in the value as a regular parameter 实际上,大多数库(包括jquery)都不要强迫您使用this并且也将值作为常规参数传递

    $('.personName').mouseover(function(event) {
        obj.highlight($(event.target).attr('faceIndex'));
    });

ambiguity solved! 歧义解决了!

Avoid using this in JavaScript, if at all possible. 尽可能避免在JavaScript中使用this It is almost never necessary. 几乎没有必要。

this in javascript is a very difficult thing to understand in callbacks because it may refer to virtually any instance. this在JavaScript是一件非常困难的事情在回调中理解,因为它可能涉及到了任何实例。 And that is because the callback is called from a different context. 那是因为回调是从不同的上下文中调用的。

The long story : https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/this 漫长的故事: https : //developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/this

As an alternative to previous answers : 作为先前答案的替代方法:

One way I prefer dealing with it is by using a bind , also known as a proxy (in JQuery). 我更喜欢处理它的一种方法是使用bind (在JQuery中也称为proxy )。 jQuery has one implemented here : jQuery.proxy . jQuery在这里实现了一个: jQuery.proxy

It has the benefit of letting you chose who is your this in the callback function. 它的好处是让您在回调函数中选择谁是您的this

For example: 例如:

var obj = {
    foo: function() {
        $('.personName').mouseover($.proxy(function(event) {
          // this refers here to obj instance
          console.log(this);
          // event is a jQuery decorated that holds the reference of your element 
          console.log(event);
        }, this));
    }
};

And the true benefit of it, is that it lets you construct components that don't have "ugly" nested callback anonymous functions: 它的真正好处是,它使您可以构建没有“丑陋”的嵌套回调匿名函数的组件:

var obj = {
    foo: function() {
        $('.personName').mouseover($.proxy(this.mouseOverCallback, this));
    },
    mouseOverCallback : function(event) {
       // this refers here to obj instance
       console.log(this);
       // event is a jQuery decorated that holds the reference of your element 
       console.log(event);
    }
};

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM