本文系统介绍 ECMAScript 的核心特性,涵盖变量声明、五种原始数据类型(Undefined、Null、Boolean、Number、String)及引用类型。详细解析数据转换方法如 parseInt、parseFloat 和 Boolean 转换,以及 Object、String 等内置类的常用方法。此外,还探讨了函数定义、参数处理及 ECMAScript 中不支持函数重载的机制与替代方案。
ECMAScript 基本特性与语法规范
ECMAScript 作为 JavaScript 的核心,其语言特性与 Java、C 及 Perl 等语言存在诸多相似之处,许多特性直接借鉴自这些语言,同时也保留了独特的差异。以下将列举 ECMAScript 的基本特性。
与 Java 类似,ECMAScript 严格区分大小写,注释格式一致,并通过大括号 {} 界定代码块。在内存管理上,原始数据类型的数据存储在栈内存中,而对象的引用则存储在堆内存中。
ECMAScript 是一种弱类型(松散类型)语言。使用 var 操作符声明变量时,无需指定具体类型。例如,执行 var n = 25 时,n 被识别为数字类型;若执行 var n = "string",则 n 变为 String 类型。
在 ECMAScript 中,行末的分号是可选的,解释器会自动在行尾插入分号(ASI 机制)。此外,变量在声明时可以不进行初始化,系统会在后台自动完成初始化操作。
ECMAScript 允许同一变量被赋予不同类型的数据。变量名的首字符必须是字母、下划线(_)或美元符号($),后续字符可以是字母、数字、下划线或美元符号。
遵循编程惯例,变量命名推荐采用驼峰命名法(camelCase)、帕斯卡命名法(PascalCase)或匈牙利命名法,以提高代码可读性。
与其他语言不同,ECMAScript 允许在使用前不声明变量。若直接赋值,系统会将其隐式声明为全局变量。例如:var m = "Good"; n = m + " Morning"; alert(n) 将输出 "Good Morning"。
在大多数编程语言中,String 被视为对象类型,但在 ECMAScript 中,String 被归类为原始数据类型。
原始数据类型详解
原始数据类型
ECMAScript 定义了五种原始数据类型:Undefined、Null、Boolean、Number 和 String。
使用 typeof 操作符可以判断变量或值的数据类型,其返回值通常包括 undefined、boolean、number、string 和 object 五种。
Undefined 类型:当变量已声明但未初始化,或者函数没有显式返回值时,该变量或函数的返回值为 Undefined。
Null 类型:Undefined 是 Null 的派生值。当表示对象引用不存在时,该对象的值为 null。
Boolean 类型:包含 true 和 false 两个值。注意,false 不等于数字 0,但数字 0 可以隐式转换为 false。
Number 类型:支持定义 32 位整型或 64 位浮点型数据。定义数字时,前缀 0 表示八进制,前缀 0x 表示十六进制,计算结果统一为十进制。通过 var f = 1.0 可定义浮点变量。有趣的是,在参与计算前,浮点数在内部可能以 String 类型存储。对于极大或极小的浮点数(小数点移动超过六位),使用指数表示法(E 表示法),最大可存储 17 位有效数字。此外,isFinite() 用于判断数值是否有限,isNaN() 用于判断是否为非数字。
String 类型:在 ECMAScript 中,String 是原始数据类型,且是唯一没有固定空间大小限制的类型。与 Java 不同,var s = "javascript" 和 var s = 'javascript' 均为合法的字符串表示方式。
数据转换机制
数据转换
数据类型转换是编程语言的重要特性。ECMAScript 提供了多种简单的方法进行数据转换,大多数原始数据类型都内置了转换方法,复杂转换则通过全局函数实现,整体转换过程较为简便。
Boolean、Number 和 String 既是原始数据类型,也被视为伪对象(关于 ECMAScript 中伪对象的具体解释及运行机制尚存争议,欢迎补充)。它们拥有自己的属性和方法,可通过 toString() 方法转换为字符串。ECMAScript 定义所有对象(无论真假)均具备 toString() 方法,因此 String 作为伪对象也拥有此方法。在将数字转换为字符串时,可在 toString() 中传入 2、8 或 16 作为参数,以指定输出的进制。例如:var n = 10; alert(n.toString(2)) 输出 1010,alert(n.toString(8)) 输出 12,n.toString() 与 n.toString(10) 效果相同。
ECMAScript 提供了两种将字符串转换为数字的方法:parseInt() 和 parseFloat()。若尝试转换其他类型,通常会返回 NaN(Not a Number)。
Type Casting
ECMAScript 中的数据类型转换通常通过 Boolean(value)、Number(value) 和 String(value) 三个全局函数实现,这可能会产生一些非预期的结果。
Boolean
var b1 = Boolean( "" ); // false–空字符串
var b2 = Boolean( " hi " ); // true–非空字符串
var b3 = Boolean( 100 ); // true–非零数字
var b4 = Boolean( null ); // false–null
var b5 = Boolean( 0 ); // false–零
var b6 = Boolean( new Object()); // true–对象
Number
Number( false ) 0
Number( true ) 1
Number(undefined) NaN
Number( null ) 0
Number( " 5.5 " ) 5.5
Number( " 56 " ) 56
Number( " 5.6.7 " ) NaN
Number( new Object()) NaN
Number( 100 ) 100
String
String() 函数可实现所有类型数据的直接转换。与 toString() 不同,String() 能够将 null 或 undefined 转换为字符串。
引用类型与内置类
引用类型
ECMAScript 实际上没有传统意义上的类,而是通过定义对象来模拟其他语言中的类。这一点较为模糊,后续可能会更清晰,但在本文中仍沿用“类”这一概念进行说明。
var ob = new Object();
上述代码定义了一个 Object 对象的实例,语法与 Java 类似。当有参数时需要使用括号,无参数时括号可省略。由于 ECMAScript 语言特性较为松散,无论是基础语法还是后续高级语法,都建议遵循一定的书写规范来约定代码格式,而不应过度利用语言的松散特性。
Object类
Object 类类似于 Java 中的 java.lang.Object 类,它是 ECMAScript 中所有其他类的基类,具有以下属性:
constructor—指向创建该对象的函数的引用。对于 Object 类,该引用指向本地的 Object() 方法。
prototype—指向对象原型对象的引用值。
Object 类拥有的方法:
hasOwnProperty(property)—判断 property 属性是否存在于对象中,property 数据类型为 string。
isPrototypeOf(object)—判断一个对象是否是另一个对象的原型。
propertyIsEnumerable(property)—判断所给出的属性是否可以使用 for 语句列举出来。
toString()—返回对象的原始类型字符串。
valueOf()—返回对象合适的原始值,对于大多数类而言,返回值与 toString() 相同。
Object 类的每一个属性和方法都会被其他类重写。
Boolean类
定义方法 var ob = new Boolean(true); ob 是 Boolean 原始数据类型的一个引用。在使用 Boolean 对象时需注意,所有对象在布尔上下文中会自动转换为 true。因此,var ob1 = new Boolean(false); var ob2 = ob1 && true; 最后 ob2 的值为 true,而非 false。一般情况下,使用 Boolean 原始数据类型可避免此类问题。
Number类
定义方法 var o = new Number(15);
获得原始数据的值 var n = o.valueOf();
Number 类有一些为数字类型特别设计的方法:
alert(o.toFixed( 2 )); // 输出15.00
alert(o.toExponential( 1 )); // 输出1.5e+1
在无法确定使用 toFixed 还是 toExponential 时,可以使用 toPrecision 方法获取取值:
alert(o.toPrecision( 1 )); // 输出 2e+1
alert(o.toPrecision( 2 )); // 输出 15
alert(o.toPrecision( 3 )); // 输出 15.0
String类
String 类是一种复杂的引用类型,此处仅列出一些常见方法,其中不少模仿自 java.lang.String:
var s = new String( " Good Morning " );
alert(s.valueOf() == s.toString()); // 输出true
alert(s.length); // 输出12
alert(s.charAt( 1 )); // 输出o
var sr = s.concat( " ! " ); alert(sr); // 输出Good morning !
alert(s.indexOf( " o " ); // 输出1
alert(s.lastIndexOf( " o " ); // 输出6
alert(s.localeCompare(Good morning)); // 输出0
alert(s.localeCompare(Apple)); // 输出1
alert(s.localeCompare(House)); // 输出-1
alert(s.slice( 2 )); // 输出od morning
alert(s.substring( 2 )); // 输出od morning
alert(s.slice( 2 , - 5 )); // 输出od mo
alert(s.substring( 2 , - 5 )); // 输出Go
alert(s.toUpperCase()); // 输出GOOD MORNING
alert(s.toLowerCase()); // 输出good morning
此外,所有 String 类的方法同样可用于 String 原始数据类型,因为它是伪对象。
instanceof
instanceof 操作符与 typeof 作用类似,不同之处在于,instanceof 需要明确指定对象是否属于某种特定类型。例如:
var s = new String( " Good morning ! " );
alert(s instanceof String);
操作符、语句与函数核心
操作符和语句
ECMAScript 中的大多数操作符和语句与 Java 类似,但也有一些特有语句,如 label 语句、with 语句、for-in 语句等。
Functions
Functions 是 ECMAScript 的核心,是一组可以在任何时间、任何地方运行的代码语句。
function functionName(arg0, arg1, …… , argN) {
statements
}
当 function 没有返回值或 return 语句后没有值时,该 function 实际上会被系统定义为 undefined。当 function 有返回值时,无需明确指定其数据类型。
关于重载
重载是面向对象语言的基本特性,但 ECMAScript 的 functions 不支持重载。在同一作用域内可以定义两个完全相同的函数,调用时只有最后一个定义的函数生效。这一特性较为麻烦,但可以通过 arguments 对象实现类似重载的功能。
function func() {
if (arguments.length == 1 ) {
alert(arguments[ 0 ] + 5 );
} else if (arguments.length == 2 ) {
alert(arguments[ 0 ] + arguments[ 1 ]);
}
}
func( 5 ); // 输出10
func( 10 , 15 ); // 输出25
前文提到,在同一作用域内可以定义两个完全相同的 function,调用时只有最后一个 function 生效。
function func(i) {
alert(i + 10 );
}
function func(i) {
alert(i + 20 );
}
func( 5 ); // 输出25
可以看出,结果是调用了最后一个 function 导致数据结果为 25。如果使用 Function 类来定义上述两个函数,为何会使用最后一个 function 可能会更明确。
var func = new Function(“i”, “alert(i + 10 )”);
var func = new Function(“i”, “alert(i + 20 )”);
func( 5 );
func 指向了另一个引用,从而值发生了改变。func 作为 function 对象的引用存在,并允许两个变量指向同一个 function。
与 Function 类相关的属性、方法有许多,例如 length、toString()、valueOf() 等。其中 toString() 在调试程序中较为常用。
原文:http://www.blogjava.net/flyingis/archive/2006/06/13/52484.html