4

我知道关于这个主题还有其他几篇文章,但它们仍然让我感到困惑。

我已经包含了 jQuery 和所有内容,并且我有一个简单的 javascript 类,如下例所示:

function CarConstructor(){
  this.speed=19; // in mph
  this.make="Ford";
  this.fillKph=fillKph;
}

function fillKph(){
  $("#kphdiv").html(this.speed*1.61);
}

car1 = new CarConstructor();
car1.fillKph();

现在我知道该代码段不起作用并且构造不正确。

那里的“this”关键字引用了我的 dom 元素,其 id 为“kphdiv”。

我的问题是处理这个问题的最佳方法是什么。

我见过一种方法,您可以设置一些等于 this 的变量(绑定它),然后使用该变量来引用您的对象。例如:

function CarConstructor(){
  this.speed=19; // in mph
  this.make="Ford";
  this.fillKph=fillKph;
}

function fillKph(){
  var me=this;
  $("#kphdiv").html(me.speed*1.61);
}

car1 = new CarConstructor();
car1.fillKph();

我也可以让 me 成为一个全局变量……我不知道。

我只是好奇是否有另一种/更好的方法。

4

4 回答 4

10

哦,男孩,你混淆了很多事情。

function CarConstructor(){
  this.speed=19; // in mph
  this.make="Ford";
  this.fillKph; // <-> This particular statement has no meaning. 
  //When you write this.fillKph without any assignment, it will be 'undefined'. 
  //Just because you have a function named 'fillKph' somewhere else, 
  //it doesn't mean it will get attached to this property.
}

尝试,

var toyota = new Car();
alert(typeof toyota.fillKph); //will alert undefined.

fillKph 函数是在全局范围内创建的,即作为“Window”对象的属性。

function fillKph(){
  var me=this;
  $("#kphdiv").html(me.speed*1.61);
}

要修复它,您可以使用 rezzif 的建议。您的最终代码将如下所示

function Car()
{
  this.speed=19; // in mph
  this.make="Ford";
  this.fillKph = function (){
      $("#kphdiv").html(this.speed*1.61);
  };
}

car1 = new Car();
car1.fillKph();

如果您注意到,我没有在局部变量中存储对“this”的引用。为什么?在这种情况下没有必要。要了解更多信息,请在此处查看我的详细答案

如果要创建大量 Car 对象,可以在原型上定义 fillKph 方法。

function Car()
{
  this.speed=19; // in mph
  this.make="Ford";
}

Car.prototype.fillKph = function fillKph() { $("#kphdiv").html(this.speed*1.61); };

car1 = new Car();
car1.fillKph();

编辑:

如果你做类似的事情,

function CarConstructor(){
  this.speed=19; // in mph
  this.make="Ford";
  this.fillKph = fillKph;
}

function fillKph(){
  $("#kphdiv").html(me.speed*1.61);
}

car1 = new Car();
car1.fillKph(); //This will work as expected.

但问题是 fillKph 是在 'Window' 范围内定义的,所以我可以直接调用它,

fillKph(); //Calling it this way will break it as it won't get correct 'this'.

重点是,

alert(typeof fillKph); // alerts 'function' if you do it your way,
alert(typeof fillKph); // alerts 'undefined', if you do it the way I suggested, which is preferred in my opinion.
于 2009-07-29T02:58:08.070 回答
3

function CarConstructor(){
  var _this = this;  
  this.speed=19; // in mph
  this.make="Ford";
  this.fillKph = function (){
      $("#kphdiv").html(_this.speed*1.61);
  };
}

car1 = new CarConstructor();
car1.fillKph();
于 2009-07-29T02:48:02.687 回答
1

后一种方法完全没有问题,它非常好,并且可能是最优雅的方法,它只是在该点和时间存储对执行上下文的引用,以便在引用指向不同对象的另一个执行上下文中使用.

于 2009-07-29T02:49:29.520 回答
-1

The confusing thing about this in javascript is it's relationship to the new operator. As you walk up the scope chain, this always refers to the last occruance of new. If need be, that means going all the way back to the window object. So if you have something like this:

function MyObject() 
{ 
    this.baz = "some value"; 
    this.bar = function() { return this.baz; }
}
var foo = new MyObject();
alert(foo.bar());

it works as expected, because the foo variable was created with a new object/scope for the this keyword, and so the reference to this.baz points to the right place.

But then if you do this:

var foo = new MyObject();
var bar = foo.bar;
alert(bar());

expecting to call foo's bar function, you're now calling it outside of the "scope" created for foo by the new operator. Your use of this inside the bar function now looks at the window object, which doesn't have a definition for baz.

That may seem like an edge case, but it's important when working with frameworks like jQuery that create a lot of implicit objects using new or that expect you to pass functions around like variables. You have to be very careful.

于 2009-07-29T03:34:28.953 回答