使用setTimeout的自定义对象调用方法会丢失范围 [英] Custom Object calling Methods with setTimeout loses scope

查看:76
本文介绍了使用setTimeout的自定义对象调用方法会丢失范围的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在构建Javascript对象时遇到问题,并使用setTimeout调用该对象中的方法。我尝试了各种变通方法,但总是在循环的第二部分中,范围变为窗口对象而不是我的自定义对象。警告:我是javascript的新手。

I'm having an issue with building a Javascript object, and calling methods within that object using setTimeout. I've tried various workarounds, but always during the second part of my loop the scope becomes the window object rather than my custom object. Warning: I'm pretty new at javascript.

我的代码:

$(function() {
 slide1 = Object.create(slideItem);
 slide1.setDivs($('#SpotSlideArea'));
 slide1.loc = 'getSpot';
 slide2 = Object.create(slideItem);
 slide2.setDivs($('#ProgSlideArea'));
 slide2.loc = 'getProg';
 slide2.slide = 1;
 setTimeout('triggerSlide(slide1)', slide1.wait);
 setTimeout('triggerSlide(slide2)', slide2.wait);
});

function triggerSlide(slideObject) {
 slideObject.changeSlide(slideObject);
}

var slideItem = {
 div1: null,
 div2: null,
 slide: 0,
 wait: 15000,
 time: 1500,
 loc: null,
 changeSlide: function(self) {
  this.slide ? curDiv = this.div1:curDiv = this.div2;
  $(curDiv).load(location.pathname + "/" + this.loc, this.slideGo(self));
 },
 setDivs: function(div) {
  var subDivs = $(div).children();
  this.div1 = subDivs[0];
  this.div2 = subDivs[1];
 },
 slideGo: function(self) {
  if(this.slide) {
   $(this.div2).animate({
    marginLeft: "-300px"
   }, this.time);
   $(this.div1).animate({
    marginLeft: "0"
   }, this.time);
   setTimeout('triggerSlide(self)', this.wait);
  } else {    
   $(this.div1).animate({
    marginLeft: "300px"
   }, this.time);
   $(this.div2).animate({
    marginLeft: "0"
   }, this.time);
   setTimeout('triggerSlide(self)', this.wait);
  }   
  this.slide ? this.slide=0:this.slide=1;
 }
}

我最近的尝试是构建辅助函数triggerSlide,以便我可以尝试通过我的方法将引用传递给对象,但即便如此也不行。

My latest attempt was building the helper function triggerSlide so that I could attempt to pass the reference to the object through my methods, but even that doesn't seem to work.

我可以使用setInterval但它可以工作,但是:

I could use setInterval and it works, however:


  1. 我想确保在计时器重启之前动画已经完成

  2. 我不知道如何以这种方式解决问题。 :)


推荐答案

这对于Javascript程序员开始使用该语言应该是必读的(和使用Stackoverflow)。

This should be required reading for Javascript programmers getting started with the language (and with Stackoverflow).

与Java不同,函数没有内在的绑定任何对象,无论它们是如何声明的。对象上下文的绑定仅在函数调用时发生。因此,当您将对函数的引用传递给类似setTimeout之类的东西时,从某个对象获取该函数并不重要。它只是一个函数,setTimeout将使用默认上下文调用它— 窗口对象。

Unlike Java, there's no intrinsic "binding" of functions to any object, regardless of how they're declared. The binding of object context happens only at function invocation time. Thus, when you pass a reference to a function to something like "setTimeout", it doesn't matter at all that you got the function from some object. It's just a function, and "setTimeout" will call it with the default context — the window object.

有很多方法可以解决这个问题(我不会称之为问题) ;这是语言的一个事实,而且非常强大。如果你使用的是某种类型的框架,它会更容易。

There are many ways to handle this (and I won't call it a "problem"; it's a fact of the language, and a very powerful one). If you were using a framework of some kind it'd be easier.

另一件事:你将超时和间隔处理程序绑定为包含代码的字符串。这是一个非常丑陋的练习,所以你应该习惯于形成函数表达式—也就是说,其值是函数的表达式。

Another thing: you're binding your timeout and interval handlers as strings containing code. That's a pretty ugly practice, so you should get used to forming function expressions — that is, expressions whose values are functions.

例如,对于你的slideItem处理程序,你可以这样做:

For your "slideItem" handler, for example, you might do this:

// ...
setTimeout(function() { slideItem.changeSlide(); }, 5000);

这样,超时机制调用的函数将始终使用slideItem调用changeSlide对象作为上下文。你在changeSlide中不需要那个self参数,因为this将指向正确的对象。

That way, the function called by the timeout mechanism will always invoke "changeSlide" with your "slideItem" object as the context. You don't need that "self" parameter in "changeSlide" because "this" will point to the right object.

[edit]我注意到你实际上是使用jQuery,这是一件好事。

[edit] I note that you are in fact making some use of jQuery, which is a good thing.

这篇关于使用setTimeout的自定义对象调用方法会丢失范围的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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