JavaScript / jQuery中的变量scope(this) [英] JavaScript/jQuery variable scope in class (this)

查看:111
本文介绍了JavaScript / jQuery中的变量scope(this)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我为我的网站编写简单的滑块。此滑块包含列表项。我想使用OOP方法。



我的实际代码:

  var miniSlider = function(objId)
{
this.obj = $(#+ objId);
this.obj.settings = [];
this.obj.settings ['items'] = $('ul li',this.obj).length;

this.pagerNext = this.obj.find(i.next);
this.pagerPrev = this.obj.find(i.prev);
this.pagerNext.on(click,function(){
alert(this.obj.settings ['items']);
});
};

我可以调用一些其他滑块(是的,这就是为什么我引入了一个类):

  miniSlider(mini-slider);问题是,当我在jQuery的this.pagerNext.on(点击,功能) (){});    不再是我的对象,而是成为点击的元素。 



编辑: 如果在完成点击后访问this.obj.settings p>

以下是与SOF社区合作创建的完整代码:)

  var MiniSlider = function(objId)
{
this.obj = $(#+ objId);

this.obj.settings = {
items:$(ul li,this.obj).length,
autoChangeTime:8000
};
this.obj.activeElement = null;

this.pagerNext = this.obj.find(i.next);
this.pagerPrev = this.obj.find(i.prev);

var self = this;

this.pagerNext.on(click,function(){

self.obj.activeElement = $('li.active',self.obj);

if(self.obj.settings.items> 0)
{
if(self.obj.activeElement.is(':last-child'))
{
$('li.active',self.obj).removeClass('active');
$('li',self.obj).first()。addClass );
}
else
{
self.obj.activeElement.next()。addClass('active')。prev()。removeClass('active');
}
}
});
this.pagerPrev.on(click,function()
{
self.obj.activeElement = $('li.active',self.obj);

if(self.obj.settings.items> 0)
{
if(self.obj.activeElement.is(':first-child'))
{
self.obj.activeElement.removeClass('active');
$('li',self.obj).last()。addClass('active');
}
else
{
self.obj.activeElement.prev()。addClass('active')。next()。removeClass('active');
}
}
});
this.obj.parent()。on('mouseenter mouseleave',function(e){
if(e.type =='mouseenter')
{
$ this)。addClass('stop');
}
else
{
$(this).removeClass('stop');
}
});
setInterval(function(){
if(self.obj.settings.items> 0&&!self.obj.parent()。hasClass(stop))
{
self.pagerNext.click();
}
},this.obj.settings.autoChangeTime);

};

并调用:

  new MiniSlider(mini-slider); 


解决方案

Alex为您提供<$ c $



您正在调用 miniSlider ()运算符的函数:

  miniSlider(mini-slider); 

这意味着在函数内, this 不是唯一的对象,但实际上是窗口对象!



您需要使用 new 运算符为每个调用创建单独的对象:

  new miniSlider滑块); 

但是,您还应该更改此函数的名称,以遵循JavaScript约定,信。调用 MiniSlider 并使用它:

 迷你滑块); 

如果你遵循这个惯例(大多数经验丰富的JavaScript程序员所做的),它会帮助你记住什么时候使用 new 。如果函数以大写字母开头,它是一个构造函数,你需要使用 new

new

如果您希望能够使用您的构造函数 / code>,也可以用更多的代码,例如:

  function MiniSlider(objId){
if(this == window)return new MiniSlider(objId);
//其余的构造函数代码放在这里
}

人们不用担心,只是使用构造函数上的初始大写字母作为提醒使用 new



另外,作为建议,我喜欢在一个变量中保存 this 时使用有意义的名称,然后我使用该名称而不是使用 this 。这样做它可能看起来像:

  var miniSlider = function(objId){
var slider = this;

slider.obj = $(#+ objId);
slider.obj.settings = [];
slider.obj.settings ['items'] = $('ul li',slider.obj).length;

slider.pagerNext = slider.obj.find(i.next);
slider.pagerPrev = slider.obj.find(i.prev);
slider.pagerNext.on(click,function(){
alert(slider.obj.settings ['items']);
});
};

为什么我更喜欢使用 this 在大多数地方和另一个变量如 self 在哪里你需要它?这样我不必记住使用哪个:我可以总是在代码中使用 slider ,而不是 。 (当然你可以使用 self 或任何其他名称;我只是想有一个更有意义的名称,如果我要去做一个名字的麻烦。 )



代码中的另一个小问题是这两个语句:

  slider.obj.settings = []; 
slider.obj.settings ['items'] = $('ul li',slider.obj).length;

您不应该使用 Array 你将要给它这样命名的属性。请改用 Object 。只有当你有数字索引(如0,1,2等)时,才应使用数组。使用对象字面值,您可以同时设置属性:

  slider.obj.settings = {
items:$('ul li',slider.obj).length
};

此外,当您使用该属性时:

  alert(slider.obj.settings ['items']); 

您可以更简单地写为:

  alert(slider.obj.settings.items); 

任何一种方式都可以做同样的事情。


I'm writing simple slider for my website. This slider contains list items. I want to use OOP approach.

My actual code:

var miniSlider = function(objId)
    {
        this.obj = $("#" + objId);
        this.obj.settings = [];
        this.obj.settings['items'] = $('ul li', this.obj).length;

        this.pagerNext = this.obj.find("i.next");
        this.pagerPrev = this.obj.find("i.prev");
        this.pagerNext.on("click", function() {
        alert(this.obj.settings['items']);
        });
    };

I can invoke a few other sliders (yes, that's why I introduced a class):

miniSlider("mini-slider");

The problem is that when I'm in jQuery this.pagerNext.on("click", function() { }); this is no longer my object but - it's become a clicked element. How can I access this.obj.settings after click in a well done way (and with multi sliders support)?

EDIT:

Here is a full code created with a cooperation with SOF community :)

var MiniSlider = function(objId)
{
    this.obj = $("#" + objId);

    this.obj.settings = {
        items: $("ul li", this.obj).length,
        autoChangeTime: 8000
    };
    this.obj.activeElement = null;

    this.pagerNext = this.obj.find("i.next");
    this.pagerPrev = this.obj.find("i.prev");

    var self = this;

    this.pagerNext.on("click", function() {

        self.obj.activeElement = $('li.active', self.obj);

        if(self.obj.settings.items > 0)
        {
            if(self.obj.activeElement.is(':last-child')) 
            { 
                $('li.active', self.obj).removeClass('active');
                $('li', self.obj).first().addClass('active');
            } 
            else 
            {
                self.obj.activeElement.next().addClass('active').prev().removeClass('active');
        }
    }
    });
    this.pagerPrev.on("click", function() 
    {
        self.obj.activeElement = $('li.active', self.obj);

        if(self.obj.settings.items > 0)
        {
            if(self.obj.activeElement.is(':first-child')) 
            { 
                self.obj.activeElement.removeClass('active');
                $('li', self.obj).last().addClass('active');
            } 
            else 
            {
                self.obj.activeElement.prev().addClass('active').next().removeClass('active');
            }
        }
    });
    this.obj.parent().on('mouseenter mouseleave', function(e) {
        if (e.type == 'mouseenter') 
        {
            $(this).addClass('stop');
        }
        else 
        {
            $(this).removeClass('stop'); 
        }
    });
    setInterval(function() {
        if(self.obj.settings.items > 0 && !self.obj.parent().hasClass("stop"))
        {
            self.pagerNext.click();
        }
    }, this.obj.settings.autoChangeTime);

    };

and invoke:

new MiniSlider("mini-slider");

解决方案

Alex gave you the solution to the this problem in your callback, but there is another problem in your code.

You are calling the miniSlider() function without a new operator:

miniSlider("mini-slider");

That means that inside the function, this is not a unique object, but is actually the window object!

You need to use the new operator to create an individual object for each call:

new miniSlider("mini-slider");

But you should also change the name of this function to follow the JavaScript convention that constructors begin with a capital letter. Call it MiniSlider and use it like so:

new MiniSlider("mini-slider");

If you follow this convention (which most experienced JavaScript programmers do), it will help you remember when to use new. If the function begins with a capital letter, it's a constructor and you need to use new with it. Otherwise, you don't.

If you'd like to be able to use your constructor without new, that is also possible with a bit more code, e.g.:

function MiniSlider( objId ) {
    if( this == window ) return new MiniSlider( objId );
    // the rest of your constructor code goes here
}

But generally people don't bother with that and just use the initial capital letter on the constructor as a reminder to use new.

Also, as a suggestion, I like to use a meaningful name when I save this in a variable, and then I use that name consistently instead of using this at all. Doing it this way it might look like:

var miniSlider = function(objId) {
    var slider = this;

    slider.obj = $("#" + objId);
    slider.obj.settings = [];
    slider.obj.settings['items'] = $('ul li', slider.obj).length;

    slider.pagerNext = slider.obj.find("i.next");
    slider.pagerPrev = slider.obj.find("i.prev");
    slider.pagerNext.on("click", function() {
        alert(slider.obj.settings['items']);
    });
};

Why do I prefer that approach over using this in most places and another variable like self where you need it? This way I don't have to remember which to use: I can always use slider in the code instead of this. (Of course you could use self or any other name; I just like to have a more meaningful name if I'm going to the trouble of making up a name at all.)

Another minor problem in the code is in these two statements:

    slider.obj.settings = [];
    slider.obj.settings['items'] = $('ul li', slider.obj).length;

You shouldn't use an Array when you are going to be giving it named properties like this. Use an Object instead. Arrays should only be used when you have numeric indexes like 0, 1, 2, etc. And with an object literal you can set the property at the same time:

    slider.obj.settings = {
        items: $('ul li', slider.obj).length
    };

Also, when you use that property:

        alert(slider.obj.settings['items']);

you can write it more simply as:

        alert(slider.obj.settings.items);

Either way it does the same thing.

这篇关于JavaScript / jQuery中的变量scope(this)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆