If you're seeing this message, it means we're having trouble loading external resources on our website.

如果你被网页过滤器挡住,请确保域名*.kastatic.org*.kasandbox.org 没有被阻止.

主要内容

静态函数与实例方法

在开始算法 #3 (朝向光标加速) 之前,们需要涉及到向量和 PVector 对象的一个相当重要方面:使用静态函数和实例方法之间的区别。
暂时忘记向量,请看下面的代码:
var x = 0;
var y = 5;
x = x + y;
很简单吧?x 的值为 0,加上 y,那么 x 现在等于 5。我们可以很容易在 PVector 对象中写出相应功能的代码。
var v = new PVector(0,0);
var u = new PVector(4,5);
v.add(u);
向量 v 的值为 (0, 0),再加上 u,现在 v 等于 (4, 5)。很简单,对吧?
我们再看另一个例子:
var x = 0;
var y = 5;
var z = x + y;
x 的值为 0,把它加上 y,并将结果存储在一个新变量 z 中。这样的话 x 的值不会改变,y 也不会改变!这似乎是一个微不足道的问题,在数学方面也很直观。然而,在PVector对象中可没那么简单,我们来试写相应的代码。
var v = new PVector(0,0);
var u = new PVector(4,5);
var w = v.add(u); // 别被唬住了,这是不正确的!!!
上面的代码看起来没问题,但 PVector 对象可不能这么写。我们来看看 add() 方法的定义...
PVector.prototype.add = function(v) {
    this.x = this.x + v.x;
    this.y = this.y + v.y;
 };
...这个代码不能实现我们的目标。首先,它不会返回一个新的 PVector(代码中没有 return 语句),其次,它改变了调用它的 PVector 的值。为了将两个 PVector 对象相加并将结果返回为新的 PVector,我们必须使用 “静态”add() 函数。
“静态”函数是在对象上定义的函数,但它不会更改对象的属性。那么为什么还要在对象上定义它呢?通常情况下,它与对象有关,因此将其附加到该对象是合乎逻辑的。它对对象的影响更像是一个命名空间。例如,PVector 上的所有静态函数都对传入的 PVector 对象执行某种操作,并通常有返回值。我们当然也可以在全局定义这些函数,但用静态函数这个办法,我们可以避开全局函数,并更好的对相关功能进行分组。
我们来做一对比,下面是使用实例方法 add()
v.add(u);
这行代码修改了 v 的值,所以我们不需要保存一个返回值。相反,下面是如何使用静态函数 add()
var w = PVector.add(v, u);
如果我们不将该函数的结果保存到变量中,那么这行代码将是无用的,因为静态函数不会更改对象本身。PVector 的静态函数允许我们对 PVector 对象执行通常的数学运算,而不会改动传入的 PVectors
下面是我们编写静态函数 add() 的方法:
PVector.add = function(v1, v2) {
  var v3 = new PVector(v1.x + v2.x, v1.y + v2.y);
  return v3;
};
这里有几个区别:
  • 静态函数直接定义在对象上,而不是原型对象上
  • 在函数中没有用 this 关键字
  • 函数有返回值
PVector 对象有静态函数版本的 add()sub()mult()div()。也有无对应实例方法的其他静态函数,如 angleBetween()dot()cross()。在用 PVector 编写程序时,这些静态函数很常用。

“自然模拟”系列课程是由 Daniel Shiffman 的 "编程的本质" 衍生而来,基于 知识共享 著名-非商用性 3.0 本地化许可协议

想加入讨论吗?

尚无帖子。
你会英语吗?单击此处查看更多可汗学院英文版的讨论.