用AI赚第一桶💰低成本搭建一套AI赚钱工具,源码可二开。 广告
### 3.1 语法 ECMAScript中的一切(变量名、函数名、属性名、参数名、操作符)都区分大小写。 所谓**标识符**,就是指变量、函数、属性的名字,或者函数的参数。 * ***第一个字符必须是字母、下划线_、或美元符号$;*** * ***第二个字符可以使字母、下划线_、美元符号$或数字。*** ***按照惯例,ECMAScript标识符采用驼峰大小写格式。*** ### 3.3 变量 `var message;` 这行代码定义了一个名为message的变量,该变量可以用来保存任何值(像这样未经过初始化的变量,会保存一个特殊的值--undefined)。使用var操作符定义的变量将成为该变量的作用域中的局部变量,而省略var操作符会创建一个全局变量。 ### 3.4 数据类型 ECMAScript中有5种简单数据类型(也称为基本数据类型):Undeifined、Null、Boolean、Number和String。还有一种复杂数据类型--Object,Object本质上是由一组无序的名值对组成的。 #### 3.4.1 typeof操作符 typeof操作符用于检测给定变量的数据类型。对一个值使用typeof操作符可能返回下列某个字符串(均为小写字母): * “undefined”----如果这个值未定义; * “boolean”----如果这个值是布尔值; * “string”----如果这个值是字符串; * “number”----如果这个值是数值; * **“object”----如果这个值是对象(包括正则表达式)或者null;** * **“function”----如果这个值是函数。** #### 3.4.2 Undefined类型 Undefined类型只有一个值,即特殊的undefined。在使用var声明变量但未对其加以初始化(个人理解:初始化等同于赋值)时,这个变量的值就是undefined,例如: ~~~ var message; alert(message == undifined); //true ~~~ 对于尚未声明过的变量,只能执行一项操作,即使用typeof操作符检测其数据类型(其他操作均会产生错误)。然而令人困惑的是:**对未初始化的变量执行typeof操作符会返回undefined值,而对未声明的变量执行typeof操作符同样也会返回undefined值**。因此,即使未初始化的变量会自动被赋与undefined值,但显式地初始化变量依然是明智的选择。如果能够做到这一点,那么当typeof操作符返回”undefined”值时,我们就知道被检测的变量还没有被声明,而不是尚未初始化。 ***** 如果只是声明了一个变量而不是马上对其实际赋值,那么将其初始化的最佳实践个人总结如下: * ***Boolean类型赋值为true/false;*** * ***Number类型赋值为0;*** * ***String类型赋值为空字符串;*** * ***Object类型(空对象)赋值为null;*** #### 3.4.4 Boolean类型 要将一个值转换为其对应的布尔值,可以调用转型函数Boolean()。虽然Boolean类型的字面值只有两个,但ECMAScript中所有类型的值都有与这两个布尔值等价的值。各种数据类型及其对应的布尔值转换规则见P26。**流控制语句(如if语句)自动执行相应的Boolean转换(自动调用Boolean()函数)**。 #### 3.4.5 Number类型 Number类型的注意点包括: - ***永远不要测试某个特定的浮点数值***。 - ECMAScript中整数除了能以十进制表示外,还可以通过八进制或十六进制的字面值来表示。 - 如果某次计算返回了正或负的Infinity值,那么该值将无法继续参与下一次的计算。要想确定一个数值是不是有穷的,可以使用isFinite()函数。这个函数会在参数位于最小与最大数值之间时返回true。 - 任何涉及NaN的计算操作都会返回NaN,这个特点在多步计算中有可能导致问题;NaN与任何值都不相等,包括NaN本身。 - IsNaN()函数用于判断参数是否“不是数值”,isNaN()函数的参数可以为任何类型,在接收到一个值之后,会尝试将这个值转换为数值(个人推测是调用Number()函数)。 - Number()函数可用于任何类型的转换,而parseInt()、parstFloat()函数则专门用于把字符串转换成数值,它们之间的主要区别有两个: 1. Number()函数不接受任何包含非数字的字符串(返回NaN),而后两者的参数只要第一个非空字符为数字即会返回数值,数字后的字符串将被忽略。 2. 是Number()函数对空字符串会返回数值0,而后两者会返回NaN。 此外,Number()函数会将undefined值转换为NaN而不是0。 #### 3.4.6 String类型 字符字面量中的转义序列详见P33。他们的一致特点是用反斜杠”\”开头。(最常用的\n表示换行) ***** 要把一个值转换为一个字符串有两种方式。第一种是使用每个引用类型值都有的toString()方法,但null和undefined没有这个方法。第二种是在不知道要转换的值是不是null或undefined的情况下使用转型函数String(),这个函数可以把所有类型值转换为相应的字符串。 #### 3.4.7 Object类型 ECMAScript中的对象其实就是一组数据和功能的集合。对象可以通过执行new操作符后跟要创建的对象类型的名称来创建。**而创建Object类型的实例并为其添加属性和(或)方法,就可以创建自定义对象**。 ***** 创建一个Object类型**实例**的基本语法: `var o = new Object();` ***** 在ECMAScript中,Object类型是所有它的实例的基础。换句话说,Object类型所具有的任何属性和方法也同样存在于更具体的对象中。 ***Object的每个实例都具有下列属性和方法***: * constructor:保存着用于创建当前对象的函数。对于前面的例子而言,构造函数(constructor)就是Object()。 * hasOwnProperty(propertyName):用于检查给定的属性在当前对象实例中(而不是在实例的原形中)是否存在。其中,作为参数的属性名(propertyName)必须以字符串形式指定。(例如:o.hasOwnProperty(‘name’);)。 * isPrototypeOf(Object):用于检查当前对象是否是传入对象的原型。 * propertyIsEnumerable(propertyName):用于检查给定的属性是否能够使用for-in语句来枚举。 * toLocaleString():返回对象的字符串表示,该字符串与执行环境的地区对应。 * toString():返回对象的字符串表示; * valueOf():返回对象的字符串、数值或布尔值表示。通常与toString()方法的返回值相同。 由于在ECMAScript中Object对象是所有对象的基础,因此所有对象都具有这些基本的属性和方法。 ***** 从技术角度讲,ECMA-262中对象的行为不一定适用于JavaScript中的其他对象。浏览器环境中的对象,比如BOM和DOM中的对象,都属于宿主对象,因为它们是由宿主提供和定义的。ECMA-262不负责定义宿主对象,因此宿主对象可能会也可能不会继承Object。 ### 3.5 操作符 ECMAScript操作符的与众不同之处在于,它们能够适用于很多值,例如字符串、数值、布尔值,甚至对象。不过,在应用于对象时,相应的操作符通常都会调用对象的valueOf()和(或)toString()方法,以便取得可以操作的值。 #### 3.5.1 一元操作符 只能操作一个值的操作符叫做一元操作符。它们包括: 递增和递减操作符:++、-- 一元加和一元减操作符:+、- ***** 后置递增和递减与前置递增和递减有一个非常重要的区别,即递增和递减操作是在包含他们的语句被求值之后才执行的。 例: ~~~ var num1 = 2, num2 = 20; Var num3 = num1-- + num2; //22 Var num4 = num1 + num2: //21 ~~~ 对单个数据类型使用一元加和一元减操作符,该操作符会像Number()转型函数一样对这个值执行转换。(注:在所有转型函数中,只有Number()会对Object类型调用valueOf()和(或)toString()方法进行下一步操作。)。 #### 3.5.3 布尔操作符 ***ECMAScript程序的赋值语句经常会利用逻辑或的特性,避免为变量赋null或undefined值***: `var myObject = preferredObject || backupObject;` 在逻辑与中,如果第一个运算数为假,那么返回第一个运算数,否则返回第二个运算数。 在逻辑或中,如果第一个运算数为真,那么返回第一个运算数,否则返回第二个运算数。 ***逻辑与、逻辑或都只会进行布尔测试,而不会真正地对操作数进行转型转换*!** #### 3.5.4 乘性操作符 3个乘性操作符:乘法、除法和求模,在操作数为非数值的情况下同样会执行自动的Number()类型转换。 #### 3.5.5 加性操作符 如果应用加法操作符(+)的数据中存在字符串,则都会转换成字符串进行拼接;如果应用减法操作符(-)则全部转换为数值进行运算。 ***** **总的来说,算数操作符中,除了加法操作符会在操作数存在字符串的情况下进行String()的类型转换,其他操作符在遇到非数值类型时,都会进行Number()转换。** #### 3.5.6 关系操作符 关系操作符包括<、>、<=、>= 4个。如果两个操作数都是字符串,则会比较两个字符串对应的字符编码值。其他情况都会进行Number()转换。 #### 3.5.7 相等操作符 相等(==)和不等(!=)操作符优先进行Number()类型转换再比较。另外还要遵循下列规则: - null和undefined是相等的; - 要比较相等性之前,不能将null和undefined转换成其他值。 - 如果有一个操作数是NaN,则相等操作符返回false,而不相等操作符返回true。即使两个数都是NaN,相等操作符也返回false。 - 如果两个操作数是对象,则比较它们是不是同一个对象。如果两个操作数都指向同一个对象,则相等操作符返回true,否则返回false。 ***在实际编程中,为了保持代码中数据类型的完整性,推荐使用全等和全不等操作符。*** #### 3.5.8 条件操作符 条件操作符(也称三元操作符)的语法形式如下: `var variable = boolean_expression ? true_value : false_value;` 问号前面的表达式将进行布尔测试,相当于 ``` var variable; if (boolean_expression) { variable = true_value; } else { Varable = false_value; } ``` ## 操作符类型转换总结: - 算数操作符(++、--、一元加操作符+、一元减操作符-、加法操作符+、减法操作符-、*、/、%):除了加法操作符(+)会在其中一个操作数是字符串的情况下对其他类型操作数进行String()类型转换,其他操作符在遇到非数值类型是,都会进行Number()转换。 - 布尔操作符(!、||、&&):逻辑非(!)会进行Boolean()转换,逻辑与(&&)和逻辑或(||)不进行类型转换。 - 关系操作符(<、>、<=、>=):如果两个操作数都是字符串,则会比较两个字符串对应的字符编码值。其他情况都会进行Number()转换,再返回布尔值。 - 相等操作符(==、!=、===、!==):相等(==)和不等(!=)操作符优先进行Number()类型转换再比较。另外还要遵循特殊的规则。全等(===)和全不等(!==)操作符不进行类型转换。 ### 3.6 语句 #### 3.6.1 if语句 ***多尝试使用if...else if...else语句以精简代码,当然最佳实践是使用switch。*** #### 3.6.5 for语句 for-in语句是一种精确的迭代语句,可以用来枚举对象的属性。以下是for-in语句的语法: `for (property in expression) statement` 示例: ~~~ for (var propName in window) { document.write(propName); } ~~~ 在这个例子中,我们使用for-in语句循环来显示了BOM中window对象的所有属性。每次执行循环,都会将window对象中存在的一个属性名赋值给变量propName。这个过程会一直持续到对象中的所有属性都被枚举一遍为止。与for语句类似,这里控制语句中的var操作符也不是必须的,但是为了保证使用局部变量,我们推荐上面例子中的这种做法。 ***** 如果表示要迭代的对象的变量值为null或undefined,for-in语句在ES5之前的版本会抛出错误。建议在使用for-in循环之前,先检测确认该对象的值不是null或undefined。 #### 3.6.9 switch语句 ***switch语句可以合并使用***,例: ~~~ Switch (i) { case 25: case 35: alert(“25或35”); break; case 45: alert(“45”); break; default: alert(“other”); } ~~~ 这其实也相当于 ~~~ if (i == 25 || i==35) { alert(“25或35”); } ~~~ ### 3.7 函数 #### 3.7.1 理解参数 ECMAScript中的参数在内部是用一个数组来表示的,在函数体内可以通过arguments对象来访问这个参数数组,从而获取出传递给函数的每一个参数。 ***** 其实,arguments对象只是与数组类似(它并不是Array的实例),因为***可以使用方括号语法访问它的每一个元素,使用length属性来确定传递进来多少个参数。开发人员可以利用length属性让函数能够接收任意个参数并分别实现适当的功能***。 ***** 关于arguments的行为,还有一点比较有意思。那就是它的值永远与对应命名参数的值保持同步。没有传递值的命名参数将被自动赋予undefined值。