method 就是通过对象而被调用的一种 JavaScript function. function 可以被赋值给对象的任何变量,或属性。比如:
f 是一个 function.
o.m
=
f;
一旦定义了,我们可以这样来调用:
o.m();
o.m(x, x
+
2
);
//
如果需要参数
方法有一个非常重要的特性:用来调用方法的那个对象,在方法体内可以以 this 指针被引用。
function 和 method 虽然看上去有些不同,但本质上是没多少区别的。function 只不过是变量中保存的一些值,而变量不过是 global 对象的属性而已。所以,当你调用一个 function 的时候,本质上是调用的 global 对象的 method. 在这样的 function 里面,this 指针指代的是 global 对象。所以从技术角度来看 function 和 method 是没有区别的。
例子:
//
This function uses the this keyword, so it doesn't make sense to
//
invoke it by itself; it needs instead to be made a method of some
//
object that has "width" and "height" properties defined.
function
compute_area( )
{
return
this
.width
*
this
.height;
}
![None.gif](/Images/OutliningIndicators/None.gif)
![None.gif](/Images/OutliningIndicators/None.gif)
//
Create a new Rectangle object, using the constructor defined earlier.
var
page
=
new
Rectangle(
8.5
,
11
);
![None.gif](/Images/OutliningIndicators/None.gif)
![None.gif](/Images/OutliningIndicators/None.gif)
//
Define a method by assigning the function to a property of the object.
page.area
=
compute_area;
![None.gif](/Images/OutliningIndicators/None.gif)
![None.gif](/Images/OutliningIndicators/None.gif)
//
Invoke the new method like this:
var
a
=
page.area( );
//
a = 8.5*11 = 93.5
上面例子的写法是不好的。因为我们必须先设定 Rectangle 的长宽属性,然后调用 area 方法才显得有意义。这可能导致错误。
下面改进后的例子说明如何在 constructor 里定义函数:
//
First, define some functions that will be used as methods.
function
Rectangle_area( ) {
return
this
.width
*
this
.height; }
function
Rectangle_perimeter( ) {
return
2
*
this
.width
+
2
*
this
.height; }
function
Rectangle_set_size(w,h) {
this
.width
=
w;
this
.height
=
h; }
function
Rectangle_enlarge( ) {
this
.width
*=
2
;
this
.height
*=
2
; }
function
Rectangle_shrink( ) {
this
.width
/=
2
;
this
.height
/=
2
; }
![None.gif](/Images/OutliningIndicators/None.gif)
![None.gif](/Images/OutliningIndicators/None.gif)
//
Then define a constructor method for our Rectangle objects.
//
The constructor initializes properties and also assigns methods.
function
Rectangle(w, h)
{
//
Initialize object properties.
this
.width
=
w;
this
.height
=
h;
![None.gif](/Images/OutliningIndicators/None.gif)
![None.gif](/Images/OutliningIndicators/None.gif)
//
Define methods for the object.
this
.area
=
Rectangle_area;
this
.perimeter
=
Rectangle_perimeter;
this
.set_size
=
Rectangle_set_size;
this
.enlarge
=
Rectangle_enlarge;
this
.shrink
=
Rectangle_shrink;
}
//
Now, when we create a rectangle, we can immediately invoke methods on it:
var
r
=
new
Rectangle(
2
,
2
);
var
a
=
r.area( );
r.enlarge( );
var
p
=
r.perimeter( );
上面这个例子其实还是有缺点。它把五个函数都赋值给属性,而这就占据了可观的内存空间。一旦创建多个这样的对象,占用的内存会成倍增长。幸运的是,JavaScript 有一个解决方案:允许对象从一个原形对象(prototype object) 继承属性。下一节我们来详细探讨这个技术。