docjavascript课程(5待续)
操作方法
- 01
// 测试需要绝对值 delta = Math.abs(delta); // 如果差小于 epsilon,那么它相当接近。 if (delta < epsilon) return true; return false;} // 浮点检查函数的末尾。// 三元检查。function checkTriplet(a, b, c){ // 创建临时变量,用于交换值 var d = 0; // 先将最长的移动到位置“a”。 // 需要的话交换 a 和 b if (b > a) { d = a; a = b; b = d; } // 需要的话交换 a 和 c if (c > a) { d = a; a = c; c = d; } // 测试全部的 3 个值,看其是否为整数? if (((a % 1) == 0) && ((b % 1) == 0) && ((c % 1) == 0)) { // 如果成立,使用精确检查。 return integerCheck(a, b, c); } else { // 如果不成立,取尽可能相近的。 return floatCheck(a, b, c); }} // 三元检查函数的末尾。// 下面的三个语句赋给范例值,用于测试。var sideA = 5;var sideB = 5;var sideC = Math.sqrt(50.001);// 调用函数。调用后,'result' 中包含了结果。var result = checkTriplet(sideA, sideB, sideC);JavaScript对象JavaScript 对象是属性和方法的集合。一个方法就是一个函数,是对象的成员。属性是一个值或一组值(以数组或对象的形式),是对象的成员。JavaScript 支持四种类型的对象:内部对象、生成的对象、宿主给出的对象(如 Internet 浏览器中的 window 和 document)以及 ActiveX 对象(外部组件)。作为数组的对象在 JavaScript 中,对象和数组几乎是以相同的方式处理的。对象和数组均可以被赋予任意值,实际上数组只是一种特殊的对象。数组和对象的区别在于数组有一个“奇妙的” length 属性,而对象没有。这意味着可以给数组的一个元素赋予比其他元素更大的值。例如,myArray[100] = "hello" — 然后 length 属性将自动地被更新为 101(新长度)。同样,如果修改数组的 length 属性,将删除不再是数组部分的元素。JavaScript 中所有的对象均支持“expando”属性或那些可以在运行时动态添加和删除的属性。这些属性可以有包含数字的任意名称。如果属性的名称是简单的标识符<<参考标识符规则>>,可以在对象名称的后面加句点,例如:var myObj = new Object();// 添加两个 expando 属性,'name' 和 'age'myObj.name = "Fred";myObj.age = 42;如果属性名称不是一个简单的标识符,或者在写脚本的时候不知道,可以在方括号中使用任意表达式来索引属性。在 JavaScript 中所有 expando 属性的名称在被添加到对象之前被转换为字符串。var myObj = new Object();// 添加两个无法写在 object.property 语// 法中的 expando 属性。// 第一个属性包含无效字符(空格),// 所以必须写在方括号里。myObj["not a valid identifier"] = "This is the property value";// 第二个 expando 名称是一个数字,// 所以也必须写在方括号里。myObj[100] = "100";传统的作法是赋给数组元素以 0 开始的数字索引。这些数组元素与 length 属性相交互。然而,由于所有的数组也是对象,也支持 expando 属性。请注意,虽然如此,expando 属性并不以任何方式与 length 属性相交互。例如:// 三个元素的数组var myArray = new Array(3);// 添加数据myArray[0] = "Hello";myArray[1] = 42;myArray[2] = new Date(2000, 1, 1);// 显示数组的长度 3window.alert(myArray.length);// 添加某些 expando 属性myArray.expando = "JavaScript!";myArray["another Expando"] = "Windows";// 仍然显示 3,因为两个 expando 属性// 并不影响长度。window.alert(myArray.length);虽然 JavaScript 并不直接支持多维数组,但是可以在数组元素中存储任意种类的数据 — 包含其他数组。所以通过在另一个数组的元素里存储其他数组可以得到多维数组的特性。例如,下面的代码为最大为 5 的数字建立了乘法表:// 若是更大的表请改变本数var iMaxNum = 5;// 循环计数var i, j;// 新数组。由于数组从 0 开始计数,// 而不是 1,所以数组大小为 iMaxNum + 1。var MultiplicationTable = new Array(iMaxNum + 1);// 为每个主要的数做循环(表中的每一行)for (i = 1; i <= iMaxNum; i++){ // 生成表中的列 MultiplicationTable[i] = new Array(iMaxNum + 1); // 将乘法的结果存在行中 for (j = 1; j <= iMaxNum; j++) { MultiplicationTable[i][j] = i * j; }}window.alert(MultiplicationTable[3][4]); // 显示 12window.alert(MultiplicationTable[5][2]); // 显示 10window.alert(MultiplicationTable[1][4]); // 显示 4JavaScript 保留字JavaScript 有一些保留字不能在标识符中使用。保留字对 JavaScript 语言有特殊的含义,它们是语言语法的一部分。使用保留字在加载脚本的时候将产生编译错误。JavaScript 还有一些留作将来使用的保留字。这些字不是现在的 JavaScript 语言的一部分,然而它们是为将来的使用保留的。保留词break delete function return typeofcase do if switch varcatch else in this voidcontinue false instanceof throw whiledebugger finally new true withdefault for null try 为将来保留的词abstract double goto native staticboolean enum implements package superbyte export import private synchronizedchar extends int protected throwsclass final interface public transientconst float long short volatile当选择标识符时避免使用已经在内部 JavaScript 对象或函数中使用的词,如 String 或 parseInt。创建高级对象使用构造函数来创建对象构造函数是一个函数,调用它来例示并初始化特殊类型的对象。可以使用 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 (35)"window.alert(s + " (" + s.length + ")");// 删除前后空格s = s.trim();// 显示"leading and trailing spaces (27)"window.alert(s + " (" + s.length + ")");递归递归是一种重要的编程技术。该方法用于让一个函数从其内部调用其自身。一个示例就是计算阶乘。0 的阶乘被特别地定义为 1。更大数的阶乘是通过计算 1 * 2 * ...来求得的,每次增加 1,直至达到要计算其阶乘的那个数。下面的段落是用文字定义的计算阶乘的一个函数。“如果这个数小于零,则拒绝接收。如果不是一个整数,则将其向下舍入为相邻的整数。如果这个数为 0,则其阶乘为 1。如果这个数大于 0,则将其与相邻较小的数的阶乘相乘。”要计算任何大于 0 的数的阶乘,至少需要计算一个其他数的阶乘。用来实现这个功能的函数就是已经位于其中的函数;该函数在执行当前的这个数之前,必须调用它本身来计算相邻的较小数的阶乘。这就是一个递归示例。递归和迭代(循环)是密切相关的 — 能用递归处理的算法也都可以采用迭代,反之亦然。确定的算法通常可以用几种方法实现,您只需选择最自然贴切的方法,或者您觉得用起来最轻松的一种即可。显然,这样有可能会出现问题。可以很容易地创建一个递归函数,但该函数不能得到一个确定的结果,并且不能达到一个终点。这样的递归将导致计算机执行一个“无限”循环。下面就是一个示例:在计算阶乘的文字描述中遗漏了第一条规则(对负数的处理),并试图计算任何负数的阶乘。这将导致失败,因为按顺序计算 -24 的阶乘时,首先不得不计算 -25 的阶乘;然而这样又不得不计算 -26 的阶乘;如此继续。很明显,这样永远也不会到达一个终止点。因此在设计递归函数时应特别仔细。如果怀疑其中存在着无限递归的可能,则可以让该函数记录它调用自身的次数。如果该函数调用自身的次数太多,即使您已决定了它应调用多少次,就自动退出。下面仍然是阶乘函数,这次是用 JavaScript 代码编写的。// 计算阶乘的函数。如果传递了// 无效的数值(例如小于零),// 将返回 -1,表明发生了错误。若数值有效,// 把数值转换为最相近的整数,并// 返回阶乘。function factorial(aNumber) {aNumber = Math.floor(aNumber); // 如果这个数不是一个整数,则向下舍入。if (aNumber < 0) { // 如果这个数小于 0,拒绝接收。 return -1; } if (aNumber == 0) { // 如果为 0,则其阶乘为 1。 return 1; } else return (aNumber * factorial(aNumber - 1)); // 否则,递归直至完成。}变量范围JavaScript 有两种变量范围:全局和局部。如果在任何函数定义之外声明了一个变量,则该变量为全局变量,且该变量的值在整个持续范围内都可以访问和修改。如果在函数定义内声明了一个变量,则该变量为局部变量。每次执行该函数时都会创建和破坏该变量;且它不能被该函数外的任何事物访问。像 C++ 这样的语言也有“块范围”。在这里,任何一对“{}”都定义新的范围。JavaScript 不支持块范围。一个局部变量的名称可以与某个全局变量的名称相同,但这是完全不同和独立的两个变量。因此,更改一个变量的值不会影响另一个变量的值。在声明局部变量的函数内,只有该局部变量有意义。var aCentaur = "a horse with rider,"; // aCentaur 的全局定义。// JavaScript 代码,为简洁起见有省略。function antiquities() // 在这个函数中声明了一个局部 aCentaur 变量。{// JavaScript 代码,为简洁起见有省略。var aCentaur = "A centaur is probably a mounted Scythian warrior"; // JavaScript 代码,为简洁起见有省略。 aCentaur += ", misreported; that is, "; // 添加到局部变量。// JavaScript 代码,为简洁起见有省略。} // 函数结束。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; // 该语句永远不会执行。 } // 条件语句结束。} // 该函数定义结束。当 JavaScript 运行函数时,首先查找所有的变量声明,var someVariable;并以未定义的初始值创建变量。如果变量被声明时有值,var someVariable = "something";那么该变量仍以未定义的值初始化,并且只有在运行了声明行时才被声明值取代,假如曾经被声明过。JavaScript 在运行代码前处理变量声明,所以声明是位于一个条件块中还是其他某些结构中无关紧要。JavaScript 找到所有的变量后立即运行函数中的代码。如果变量是在函数中显式声明的 — 也就是说,如果它出现于赋值表达式的左边但没有用 var 声明 — 那么将把它创建为全局变量。复制、传递和比较数据在 JavaScript 中,对数据的处理取决于该数据的类型。按值和按引用的比较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"。检验数据当按值进行检验时,是比较两个截然不同的项以查看它们是否相等。通常,该比较是逐字节进行的。当按引用进行检验时,是看这两项是否是指向同一个原始项的指针。如果是,则比较结果是相等;如果不是,即使它们每个字节都包含完全一样的值,比较结果也为不相等。按引用复制和传递字符串能节约内存;但是由于在字符串被创建后不能进行更改,因此可以按值进行比较。这样可以检查两个字符串是否包含相同的内容,即使它们是完全独立产生的。使用数组数组下标JavaScript 中的数组是稀疏的。也就是说,如果一个数组具有三个元素,编号分别为 0、1 和 2,您就可以创建元素 50,而不必担心从 3 到 49 的参数。如果该数组有一个自动的 length 变量,(请参阅内部对象了解有关数组长度的自动监控的说明),该 length 变量被设为 51,而不是 4。当然您可以创建各元素的编号之间没有间隙的数组,不过没有必要这样做。在 JavaScript 中,对象和数组几乎相同。两个主要差别是对象没有自动长度属性,而数组没有对象的属性和方法。数组寻址使用方括号“[]”来寻址数组。方括号中是一个数值或一个值为整数的表达式。下面的示例假定在脚本的其他地方已定义了entryNum 变量,且已赋值。theListing = addressBook[entryNum];theFirstLine = theListing[1];将对象作为关联数组通常,使用点运算符“.”访问对象的属性。例如,myObject.aProperty在这里,属性名称是一个标识符。也可以用索引运算符“[]”访问对象的属性。在这里,是把对象看作一个关联数组。关联数组是一种数据结构,它可以动态地将任意的数据的值与任意的字符串相关联。例如,myObject["aProperty"] // 与上面相同。尽管索引运算符更多地用于访问数组元素,当用于对象时,索引总是以字符串文字表示的属性名称。文章来自:http://www.fmdzw.com/734.html注意访问对象属性的两种方法的重要差异。运算符属性名称作为对属性名称的处理点“.” 标识符不能作为数据处理索引“[]” 字符串文字能被作为数据处理 在运行之前并不知道属性名称时,这个差异会有用(比如基于用户输入构造对象时)。要想从一个关联数组提取所有的属性,必须用 for … in 循环。特殊字符JavaScript 提供了一些特殊字符,允许在字符串中包括一些无法直接键入的字符。每个字符都以反斜杠开始。反斜杠是一个转义字符,表示 JavaScript 解释器下面的字符为特殊字符。转义序列字符\b 退格\f 走纸换页\n 换行\r 回车\t 横向跳格 (Ctrl-I)\' 单引号\" 双引号\\ 反斜杠 请注意,由于反斜杠本身用作转义符,因此不能直接在脚本中键入一个反斜杠。如果要产生一个反斜杠,必须一起键入两个反斜杠 (\\)。JavaScript 运算符描述语言要素将两个数相加或连接两个字符串。加法运算符(+)将一个值赋给变量。赋值运算符(=)对两个表达式执行按位与操作。按位与运算符(&)将一个表达式的各位向左移。按位左移运算符(<<)对一个表达式执行按位取非(求非)操作。按位取非运算符(~)对两个表达式指定按位或操作。按位或运算符(|)将一个表达式的各位向右移,保持符号不变。按位右移运算符(>>)对两个表达式执行按位异或操作。按位异或运算符(^)使两个表达式连续执行。逗号运算符(,)返回 Boolean 值,表示比较结果。比较运算符复合赋值运算符列表。复合赋值运算符根据条件执行两个表达式之一。条件(三元)运算符(?:)将变量减一。递减运算符(--)删除对象的属性,或删除数组中的一个元素。. delete 运算符将两个数相除并返回一个数值结果。除法运算符(/)比较两个表达式,看是否相等。相等运算符(==)比较两个表达式,看一个是否大于另一个。大于运算符(>)比较两个表达式,看一个是否大于等于另一个。大于等于运算符(>=)比较两个表达式,看是否值相等并具有相同的数据类型。严格相等运算符(===)给变量加一。递增运算符(++)比较两个表达式,看是否不相等。不等运算符(!=)返回一个 Boolean 值,表明某个对象是否为特定类的一个实例。 instanceof 运算符比较两个表达式,看是否一个小于另一个。小于运算符(<)比较两个表达式,看是否一个小于等于另一个。小于等于运算符(<=)对两个表达式执行逻辑与操作。逻辑与运算符(&&)对表达式执行逻辑非操作。逻辑非运算符(!)对两个表达式执行逻辑或操作。逻辑或运算符(||)将两个数相除,并返回余数。取模运算符(%)将两个数相乘。乘法运算符(*)创建一个新对象。 new 运算符比较两个表达式,看是否具有不相等的值或数据类型不同。非严格相等运算符(!==)包含 JavaScript 运算符的执行优先级信息的列表。运算符优先级对两个表达式执行减法操作。减法运算符(-)返回一个表示表达式的数据类型的字符串。 typeof 运算符表示一个数值表达式的相反数。一元取相反数运算符(-)在表达式中对各位进行无符号右移。无符号右移运算符(>>>)避免一个表达式返回值。 void 运算符