如果我使用以下功能:
clusters.prototype.shop_iqns_selected_class = function() { if(this.viewport_width < 980) { $(this.iqns_class).each(function() { $(this.iqn).on('click', function() { if($(this).hasClass('selected')) { $(this).removeClass('selected'); } else { $(this).addClass('selected'); } }); }); } }要向clusters函数添加属性,我知道使用this.viewport_width我指的是我定义了this.viewport_width的父函数,但是当我使用jQuery选择器$(this) ,我指的是$.on()函数的父$.on() ?
If I'm using the following function :
clusters.prototype.shop_iqns_selected_class = function() { if(this.viewport_width < 980) { $(this.iqns_class).each(function() { $(this.iqn).on('click', function() { if($(this).hasClass('selected')) { $(this).removeClass('selected'); } else { $(this).addClass('selected'); } }); }); } }To add a property to the clusters function, I know that using this.viewport_width I'm referring to the parent function where I have this.viewport_width defined, but when I'm using the jQuery selector $(this), am I referring to the parent of the $.on() function ?
最满意答案
在JavaScript中, this完全由函数的调用方式定义。 jQuery的each函数都调用你给它的迭代器函数,并将其设置为每个元素值,因此在迭代器函数中, this不再引用它在其余代码中引用的内容。
这可以通过闭包的上下文中的变量轻松修复:
clusters.prototype.shop_iqns_selected_class = function() { var self = this; // <=== The variable if(this.viewport_width < 980) { $(this.iqns_class).each(function() { // Do this *once*, you don't want to call $() repeatedly var $elm = $(this); // v---- using `self` to refer to the instance $(self.iqn).on('click', function() { // v---- using $elm if($elm.hasClass('selected')) { $elm.removeClass('selected'); } else { $elm.addClass('selected'); } }); }); } }在那里我继续使用this来引用每个DOM元素,但是你可以接受迭代器函数的参数,所以没有歧义:
clusters.prototype.shop_iqns_selected_class = function() { var self = this; // <=== The variable if(this.viewport_width < 980) { // Accepting the args -----------v -----v $(this.iqns_class).each(function(index, elm) { // Do this *once*, you don't want to call $() repeatedly var $elm = $(elm); // v---- using `self` to refer to the instance $(self.iqn).on('click', function() { // v---- using $elm if($elm.hasClass('selected')) { $elm.removeClass('selected'); } else { $elm.addClass('selected'); } }); }); } }更多阅读(我在博客中关于JavaScript的帖子) :
神话方法 你必须记住thisIn JavaScript, this is defined entirely by how a function is called. jQuery's each function calls the iterator function you give it in a way that sets this to each element value, so within that iterator function, this no longer refers to what it referred to in the rest of that code.
This is easily fixed with a variable in the closure's context:
clusters.prototype.shop_iqns_selected_class = function() { var self = this; // <=== The variable if(this.viewport_width < 980) { $(this.iqns_class).each(function() { // Do this *once*, you don't want to call $() repeatedly var $elm = $(this); // v---- using `self` to refer to the instance $(self.iqn).on('click', function() { // v---- using $elm if($elm.hasClass('selected')) { $elm.removeClass('selected'); } else { $elm.addClass('selected'); } }); }); } }There I've continued to use this to refer to each DOM element, but you could accept the arguments to the iterator function so there's no ambiguity:
clusters.prototype.shop_iqns_selected_class = function() { var self = this; // <=== The variable if(this.viewport_width < 980) { // Accepting the args -----------v -----v $(this.iqns_class).each(function(index, elm) { // Do this *once*, you don't want to call $() repeatedly var $elm = $(elm); // v---- using `self` to refer to the instance $(self.iqn).on('click', function() { // v---- using $elm if($elm.hasClass('selected')) { $elm.removeClass('selected'); } else { $elm.addClass('selected'); } }); }); } }More reading (posts in my blog about this in JavaScript):
Mythical methods You must remember this更多推荐
发布评论