【赛迪网技术社区整理】
1、创建高级对象
使用构造函数来创建对象
构造函数是一个函数,调用它来例示并初始化特殊类型的对象。可以使用 new 关键字来调用一个构造函数。下面给出了使用构造函数的新示例。
var myobject = new object(); // 创建没有属性的通用对象。
var mybirthday = new date(1961, 5, 10); // 创建一个 date 对象。
var mycar = new car(); // 创建一个用户定义的对象,并初始化其属性。
通过构造函数将一个参数作为特定的 this 关键字的值传递给新创建的空对象。然后构造函数负责为新对象执行适应的初始化(创建属性并给出其初始值)。完成后,构造函数返回它所构造的对象的一个参数。
编写构造函数
可以使用 new 运算符结合像 object()、date() 和 function() 这样的预定义的构造函数来创建对象并对其初始化。面向对象的编程其强有力的特征是定义自定义构造函数以创建脚本中使用的自定义对象的能力。创建了自定义的构造函数,这样就可以创建具有已定义属性的对象。下面是自定义函数的示例(注意 this 关键字的使用)。
function circle (xpoint, ypoint, radius) {
this.x = xpoint; // 圆心的 x 坐标。
this.y = ypoint; // 圆心的 y 坐标。
this.r = radius; // 圆的半径。
}
调用 circle 构造函数时,给出圆心点的值和圆的半径(所有这些元素是完全定义一个独特的圆对象所必需的)。结束时 circle 对象包含三个属性。下面是如何例示 circle 对象。
var acircle = new circle(5, 11, 99);
使用原型来创建对象
在编写构造函数时,可以使用原型对象(它本身是所有构造函数的一个属性)的属性来创建继承属性和共享方法。原型属性和方法将按引用复制给类中的每个对象,因此它们都具有相同的值。可以在一个对象中 更改原型属性的值,新的值将覆盖默认值,但仅在该实例中有效。属于这个类的其他对象不受此更改的影响。下面给出了使用自定义构造函数的示例,circle(注意 this 关键字的使用)。
circle.prototype.pi = math.pi;
function acirclesarea () {
return this.pi * this.r * this.r; // 计算圆面积的公式为 ?r2。
}
circle.prototype.area = acirclesarea; // 计算圆面积的函数现在是 circle prototype 对象的一个方法。
var a = acircle.area(); // 此为如何在 circle 对象上调用面积函数。
使用这个原则,可以给预定义的构造函数(都具有原型对象)定义附加属性。例如,如果想要能够删除字符串的前后空格(与 vbscript 的 trim 函数类似),就可以给 string 原型对象创建自己的方法。
// 增加一个名为 trim 的函数作为
// string 构造函数的原型对象的一个方法。
string.prototype.trim = function()
{
// 用正则表达式将前后空格
// 用空字符串替代。
return this.replace(/(^\s*)|(\s*$)/g, "");
}
// 有空格的字符串
var s = " leading and trailing spaces ";
// 显示 " leading and trailing spaces
一个局部变量的名称可以与某个全局变量的名称相同,但这是完全不同和独立的两个变量。因此,更改一个变量的值不会影响另一个变量的值。在声明局部变量的函数内,只有该局部变量有意义。
var acentaur = "a horse with rider,"; // acentaur 的全局定义。
// jscript 代码,为简洁起见有省略。
function antiquities() // 在这个函数中声明了一个局部 acentaur 变量。
{
// jscript 代码,为简洁起见有省略。
var acentaur = "a centaur is probably a mounted scythian warrior";
// jscript 代码,为简洁起见有省略。
acentaur += ", misreported; that is, "; // 添加到局部变量。
// jscript 代码,为简洁起见有省略。
} // 函数结束。
var nothinginparticular = antiquities();
acentaur += " as seen from a distance by a naive innocent.";
/*
在函数内,该变量的值为 "a centaur is probably a mounted scythian warrior,
misreported; that is, ";在函数外,该变量的值为这句话的其余部分:
"a horse with rider, as seen from a distance by a naive innocent."
*/
很重要的一点是注意变量是否是在其所属范围的开始处声明的。有时这会导致意想不到的情况。
tweak();
var anumber = 100;
function tweak() {
var newthing = 0; // 显式声明 newthing 变量。
// 本语句将未定义的变量赋给 newthing,因为已有名为 anumber 的局部变量。
newthing = anumber;
//下一条语句将值 42 赋给局部的 anumber。anumber = 42;
if (false) {
var anumber; // 该语句永远不会执行。
anumber = 123; // 该语句永远不会执行。
} // 条件语句结束。
} // 该函数定义结束。
当 jscript 运行函数时,首先查找所有的变量声明,
var somevariable;
并以未定义的初始值创建变量。如果变量被声明时有值,
var somevariable = "something";
那么该变量仍以未定义的值初始化,并且只有在运行了声明行时才被声明值取代,假如曾经被声明过。
jscript 在运行代码前处理变量声明,所以声明是位于一个条件块中还是其他某些结构中无关紧要。jscript 找到所有的变量后立即运行函数中的代码。如果变量是在函数中显式声明的 ? 也就是说,如果它出现于赋值表达式的左边但没有用 var 声明 ? 那么将把它创建为全局变量。
复制、传递和比较数据
在 jscript 中,对数据的处理取决于该数据的类型。
按值和按引用的比较
numbers 和 boolean 类型的值 (true 和 false) 是按值来复制、传递和比较的。当按值复制或传递时,将在计算机内存中分配一块空间并将原值复制到其中。然后,即使更改原来的值,也不会影响所复制的值(反过来也一样),因为这两个值是独立的实体。
对象、数组以及函数是按引用来复制、传递和比较的。 当按地址复制或传递时,实际是创建一个指向原始项的指针,然后就像拷贝一样来使用该指针。如果随后更改原始项,则将同时更改原始项和复制项(反过来也一样)。实际上只有一个实体;“复本”并不是一个真正的复本,而只是该数据的又一个引用。
当按引用比较时,要想比较成功,两个变量必须参照完全相同的实体。例如,两个不同的 array 对象即使包含相同的元素也将比较为不相等。要想比较成功,其中一个变量必须为另一个的参考。要想检查两个数组是否包含了相同的元素,比较 tostring() 方法的结果。
最后,字符串是按引用复制和传递的,但是是按值来比较的。请注意,假如有两个 string 对象(用 new string("something") 创建的),按引用比较它们,但是,如果其中一个或者两者都是字符串值的话,按值比较它们。
注意 鉴于 ascii和 ansi 字符集的构造方法,按序列顺序大写字母位于小写字母的前面。例如 "zoo" 小于 "aardvark"。如果想执行不区分大小写的匹配,可以对两个字符串调用 touppercase() 或 tolowercase()。
传递参数给函数
按值传递一个参数给函数就是制作该参数的一个独立复本,即一个只存在于该函数内的复本。即使按引用传递对象和数组时,如果直接在函数中用新值覆盖原先的值,在函数外并不反映新值。只有在对象的属性或者数组的元素改变时,在函数外才可以看出。
例如(使用 ie 对象模式):
// 本代码段破坏(覆盖)其参数,所以
// 调用代码中反映不出变化。
function clobber(param)
{
// 破坏参数;在调用代码中
// 看不到。
param = new object();
param.message = "this will not work";
}
// 本段代码改变参数的属性,
// 在调用代码中可看到属性改变。
function update(param)
{
// 改变对象的属性;
// 可从调用代码中看到改变。
param.message = "i was changed";
}
// 创建一个对象,并赋给一个属性。
var obj = new object();
obj.message = "this is the original";
// 调用 clobber,并输出 obj.message。注意,它没有发生变化。
clobber(obj);
window.alert(obj.message); // 仍然显示 "this is the original"。
// 调用 update,并输出 obj.message。注意,它已经被改变了。
update(obj);
window.alert(obj.message); // 显示 "i was changed"。
检验数据
当按值进行检验时,是比较两个截然不同的项以查看它们是否相等。通常,该比较是逐字节进行的。当按引用进行检验时,是看这两项是否是指向同一个原始项的指针。如果是,则比较结果是相等;如果不是,即使它们每个字节都包含完全一样的值,比较结果也为不相等。
按引用复制和传递字符串能节约内存;但是由于在字符串被创建后不能进行更改,因此可以按值进行比较。这样可以检查两个字符串是否包含相同的内容,即使它们是完全独立产生的。
闽公网安备 35060202000074号