第八章 8.3 方法(Methods)
method 就是通过对象而被调用的一种 JavaScript function. function 可以被赋值给对象的任何变量,或属性。比如:
f 是一个 function.
一旦定义了,我们可以这样来调用:
方法有一个非常重要的特性:用来调用方法的那个对象,在方法体内可以以 this 指针被引用。
function 和 method 虽然看上去有些不同,但本质上是没多少区别的。function 只不过是变量中保存的一些值,而变量不过是 global 对象的属性而已。所以,当你调用一个 function 的时候,本质上是调用的 global 对象的 method. 在这样的 function 里面,this 指针指代的是 global 对象。所以从技术角度来看 function 和 method 是没有区别的。
例子:
上面例子的写法是不好的。因为我们必须先设定 Rectangle 的长宽属性,然后调用 area 方法才显得有意义。这可能导致错误。
下面改进后的例子说明如何在 constructor 里定义函数:
上面这个例子其实还是有缺点。它把五个函数都赋值给属性,而这就占据了可观的内存空间。一旦创建多个这样的对象,占用的内存会成倍增长。幸运的是,JavaScript 有一个解决方案:允许对象从一个原形对象(prototype object) 继承属性。下一节我们来详细探讨这个技术。
f 是一个 function.
o.m = f;
一旦定义了,我们可以这样来调用:
o.m();
o.m(x, x + 2); // 如果需要参数
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;
}
// Create a new Rectangle object, using the constructor defined earlier.
var page = new Rectangle(8.5, 11);
// Define a method by assigning the function to a property of the object.
page.area = compute_area;
// Invoke the new method like this:
var a = page.area( ); // a = 8.5*11 = 93.5
// 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;
}
// Create a new Rectangle object, using the constructor defined earlier.
var page = new Rectangle(8.5, 11);
// Define a method by assigning the function to a property of the object.
page.area = compute_area;
// 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; }
// 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;
// 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( );
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; }
// 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;
// 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) 继承属性。下一节我们来详细探讨这个技术。