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

时间:2014-11-24 23:14:54

标签: javascript jquery oop this

我偶然发现了一个问题。我有一个对象方法foo定义为:

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

所以应该发生的是,只要鼠标光标位于personName类型的HTML对象上,就应该使用HTML对象中的obj.highlight值调用faceIndex方法作为论点。但是我显然在这两个之间发生了冲突:jQuery和JavaScript之一(从obj内部引用obj)。

我可以(应该)做什么?我是否违反了一些优秀的编程习惯?

3 个答案:

答案 0 :(得分:2)

解决此问题的典型模式是使用局部变量来存储第一个this

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

使用TypeScript或ES6编译器等语言可以更轻松地使用此模式,而无需每次手动编写_this

答案 1 :(得分:1)

简短回答:做

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

更长的解释:

Javascript确实没有 的概念this。至少不会像你习惯的那样思考它。哦,关键词没问题,而且很多时候你会有所期待,但它并不像你想象的那样工作。

事实是,在javascipt中,this与任何其他参数没有什么不同。让我告诉你。

大多数人都知道,在javascript中,您可以调用此doSomething(param1, param2)之类的函数,或者像doSomething.call(null, param1, param2)这样调用函数。如果需要,可以使用.call

编写所有函数调用

在那里看到null?你传递的任何内容都是this设置的内容。

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

如果您不使用.call,运行时只需猜测您想要的值。

因此,考虑到this与任何其他参数之间的唯一区别是您不能给this一个名字!你的问题是你有两个函数作用域,而内部函数作用域有一个名为this的变量,它隐藏了外部的this

解决方案:不要使用this。实际上大多数库(包含jquery),不要强迫您使用this并将值作为常规参数传递

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

模糊解决了!

尽可能避免在JavaScript中使用this。几乎没有必要。

答案 2 :(得分:1)

javascript中的

this在回调中是很难理解的,因为它几乎可以引用任何实例。这是因为回调是从不同的上下文调用的。

长篇故事:https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/this

作为以前答案的替代方案:

我更喜欢处理它的一种方法是使用bind,也称为proxy(在JQuery中)。 jQuery在这里实现了一个:jQuery.proxy

它的好处是让您在回调函数中选择谁是this

例如:

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));
    }
};

它的真正好处在于它可以让你构建那些没有“丑陋”的组件。嵌套回调匿名函数:

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);
    }
};