Write By Monkeyfly
以下内容均为原创,如需转载请注明出处。
第 3 章 基本概念
3.1 语法
3.1.1 区分大小写
3.1.2 标识符
3.1.3 注释
3.1.4 严格模式
3.1.5 语句
3.2 关键字和保留字
3.3 变量
3.4 数据类型
3.4.1 typeof 操作符
3.4.2 Undefined 类型
3.4.3 Null 类型
3.4.4 Boolean 类型
3.4.5 Number 类型
3.4.6 String 类型
3.4.7 Object 类型
3.1 语法
ECMAScript
的语法大量借鉴了C
及其他类C
语言(如Java
)的语法。
3.1.1 区分大小写
ECMAScript
中的一切(变量、函数名和操作符)都要区分大小写。
3.1.2 标识符
指变量、函数、属性的名字,或者函数的参数。
它可以是按照下列格式规则组合起来的一个或多个字符:
- 标识符是由数字、字母、下划线
(_)
或美元符号($)
组成的。 - 但是第一个字符不能是数字,必须是一个字母、下划线
(_)
或一个美元符号($)
;
按照惯例,ECMAScript
标识符采用驼峰大小写的格式,即第一个字符小写,剩下的每个单词的首字符大写。
如:
firstSecond、myCar //【推荐写法】
原因:
- 并没有强制要求必须是这种书写格式,
- 只是为了与
ECMAScript
的内置函数和对象的命名格式保持一致。
注意:不能把关键字、保留字、true
、false
和null
用作标识符。
3.1.3 注释
ECMAScript
使用C
风格的注释,包括单行注释和多行注释(或称块级注释)。
(1)单行注释:以两个斜杠开头。
//单行注释
(2)多行注释(块级注释):以一个斜杠和一个型号(/*)
开头,以一个星号和一个斜杠(*/)
结尾。
/*
* 这是一个多行
* (块级)注释
*/
注意: 第二行和第三行都以一个星号开头的写法,这不是必需的。
原因:为了提高注释的可读性。
3.1.4 严格模式
ECMAScript 5
引入了严格模式的概念。
它为JavaScript
定义了一种不同的解析与执行模型。
在严格模式下,ECMAScript 3
中的一些不确定的行为将得到处理,而且对某些不安全的操作也会抛出错误。
(1)如果要在整个脚本文件中启用严格模式,可以在顶部添加如下代码:
"use strict"
分析:
- 这行代码看起来像是一个字符串,也没有给它赋值,但其实它是一个编译指示,就是为了告诉那些支持该语法的
JavaScript
引擎切换到严格模式。 - 这种语法是为了不破坏
ECMAScript 3
的语法而特意选定的。
(2)在函数内部的上方包含这条编译指令,也可以指定函数在严格模式下执行:
function doSomething(){
"use strict";
//函数体
}
注意:在严格模式下,JavaScript的执行结果会有很大不同。
3.1.5 语句
ECMAScript
中的语句以一个分号结尾;如果省略了分号,则由解释器确定语句的结尾。
如:
var sum = a + b //不推荐的写法
var diff = a - b; //推荐
说明:这两个语句的写法均有效。
建议:在任何时候都不要省略语句结尾的分号。
对于多条语句来说,我们可以利用C
风格的语法将它们组合到一个代码块当中。
该代码块,以左花括号({)
开头,以右花括号(})
结尾。
如:
if( test ){
test = false;
alert(test);
}
我们都知道:
对于条件控制语句来说,比如if
语句,只有在执行多条语句的情况下才要求使用代码块。
但推荐的写法是:即使代码块中只有一条语句,也要在控制语句中使用代码块。
例如:
if( test )
alert(test); //有效但容易出错,不要使用
if( test ){
alert(test); //推荐使用
}
在控制语句中使用代码块的目的:
(1)让编码意图更加清晰;
(2)降低修改代码时出错的几率;
3.2 关键字和保留字
- 关键字:一些具有特定用途的字符。
关键字的目的:
(1)用于表示控制语句的开始或结束;
(2)用于执行某些特定的操作,等。
如:if、else、do、while、switch、case、break、default、for、return、typeof、instanceof等
注意:关键字也是语言保留下来的,已经被使用了,所以不能用作标识符。
- 保留字:将来可能被用作关键字的一些字符。它们只是被提前选出来并且保留下来,目前并没有任何特定的用途。
注意:保留字也不能用作标识符。
问题1:如果使用了关键字作为标识符,会导致什么错误?
答:如果在实现ECMAScript 3
的 JavaScript
引擎中使用,会导致“Identifier Expected”
错误。【期望标识符】
问题2:如果使用了保留字作为标识符,会导致什么错误?
答:可能会,也可能不会导致同上的错误,具体取决于特定的引擎。
注意:
(1)关键字和保留字不能作为标识符使用,但是可以作为对象的属性名使用【为了ECMAScript版本兼容最好不要用】。
(2)ECMA-262
第5
版对 eval
和 arguments
施加了限制。在严格模式下,这两个名字不能作为标识符或属性名,否则会抛出错误。
3.3 变量
ECMAScript 的变量是松散类型的。
问:何为松散类型?
答:可以用来保存任何类型的数据。
我们要知道:每一个变量仅仅是一个用于保存值的占位符而已。
问:如何定义变量?
(1)定义变量时要使用 var
操作符。(注意:var
是一个关键字)
(2)其后跟一个变量名。(即一个标识符)
如: var message;
代码分析:
定义了一个名为message
的变量,该变量可以用来保存任何值。
说明:
像这样未经过初始化的变量,会保存一个特殊的值——undefined
。
ECMAScript
也支持直接初始化变量。即在定义变量的同时就可以设置变量的值。
如:
var message = "hello";
代码分析:
定义了一个名为message
的变量,并且该变量中保存了一个字符串类型的值"hello"
。
说明:
(1)像这样初始化变量,并不会把它标记为字符串类型;
(2)初始化的过程,只是给变量赋了一个值那么简单。
所以,我们可以在修改变量值的同时修改值的类型。
问:如何修改?(如下所示)
var message = "hello";
message = 100; //有效但不推荐
代码分析:
变量 message
一开始保存了一个字符串类型的值"hello"
,然后这个值又被一个数字类型的值 100
所取代。
说明:
(1)不建议修改变量中所保存值的类型。
(2)虽然不建议这种写法,但是这种操作在 ECMAScript
中完全有效。
注意:
(1)用 var
操作符定义的变量将成为 定义该变量的作用域中的局部变量。
(2)如果在函数中使用 var
定义一个变量,该变量在函数退出后就会被销毁。
例如:
function test(){
var message = "hello"; // 局部变量
}
test();
alert(message); // 错误!
代码分析:
(1)变量message
是在函数中使用var
定义的,是一个局部变量,只能在函数的作用空间内有效。
(2)当函数被调用时,就会创建message
变量,并为message
变量赋值。
(3)在函数运行后(即执行test();
后),这个message
变量又会被立即销毁。
因此,当执行到alert(message);
这行代码时,就会报错。
改善的方法就是:创建一个全局变量。
做法:定义变量的时候省略 var
操作符即可。【不推荐使用,知道有这个方法就行】
代码如下:
function test(){
message = "hello"; //全局变量
}
test();
alert(message); //“hello”
代码分析:
(1)因为省略了var
操作符,所以 message
就成了全局变量。
(2)只要调用过一次test()
函数,这个变量就有了定义,它就可以在函数外部的任何地方被访问到。
注意:
(1)省略 var
操作符定义全局变量的方式,并不推荐使用。
原因:在局部作用域中定义的全局变量很难维护。
(2)给未经声明的变量赋值,在严格模式下,会导致抛出“ReferenceError”
错误。【引用错误】
技巧:使用一条语句定义多个变量。
做法:将每个变量(初始化或不初始化的变量均可)用逗号分隔开即可,最后的一个变量用分号结尾。
例如:
var message = "hi",
found = false,
age = 22;
代码分析:
定义并初始化了3个变量。
问题:为什么多个变量的定义能放在一条语句中?
答案:因为ECMAScript是松散类型的,所以 使用不同类型初始化变量的操作 可以放在一条语句中来完成。
注意:
(1)定义多个变量时,代码中的换行和缩进不是必须的。这样做的目的是,提高代码的可读性。
(2)在严格模式下,不能定义名为 eval
或 arguments
的变量,否则会导致语法错误。
名词解释:
- 变量的声明:在定义变量时,没有给变量赋值。
- 变量的初始化:在定义变量的同时,给变量赋了一个初始值而已。
变量的定义:在定义变量时,可以给变量赋予初始值,也可以不赋予初始值。
赋予初始值: 将变量初始化了。 不赋予初始值:未将变量初始化。
3.4 数据类型
ECMAScript
中有5
种简单数据类型(也称为基本数据类型)和1
种复杂数据类型,分别是:
基本数据类型:Undefined、Null、Boolean、Number和String
。
复杂数据类型:Object
。
说明:
(1)Object
的本质:由一组无序的名值对组成的。
(2)ECMAScript
不支持任何创建自定义类型的机制,所有的值只能是上述6
种数据类型之一。
问题:这6
种数据类型也不能表示所有的数据,为什么没有再定义其他数据类型的必要了?
答案:因为ECMAScript
的数据类型具有动态性。
3.4.1 typeof操作符
因为 ECMAScript
是松散类型的,所以就需要创建一种新的手段来检测给定变量的数据类型。
因此,typeof
操作符就诞生了,它就负责提供这方面的信息。
对一个值使用typeof
操作符,可能会返回以下结果(返回下列某个字符串):
“undefined” —— //如果这个值未定义;
“boolean” —— //如果这个值是布尔值;
“string” —— //如果这个值是字符串;
“number” —— //如果这个值是数值;
“object” —— //如果这个值是对象或者null;
“function” —— //如果这个值是函数。
例如:
var msg;
console.log( typeof msg ); //返回"undefined"
var str = "123";
console.log( typeof str ); //写法一,返回"string"【推荐使用】
console.log( typeof (str) ); //写法二
说明:typeof 有两种写法。
var num = 123;
console.log( typeof num ); //返回"number"
console.log( typeof 456 ); //返回"number"
var flag = true;
console.log( typeof flag ); //返回"boolean"
var arr = ["1","2"];
console.log( typeof arr ); //返回“object”
var obj = {name:"fly",age:"18"};
console.log( typeof obj ); //返回“object”
console.log( typeof null ); //返回“object”
var fun = function(){
alert("hello world");
};
console.log( typeof fun ); //返回"function"
代码分析:
typeof
操作符的 操作数 可以是变量,也可以是 数值字面量 。
注意:
(1)typeof
是一个操作符而不是函数。
(2)虽然例子中的typeof
后面的圆括号可以使用,但并不是必需的。
(3)有时候,typeof
操作符会返回一些令人迷惑但技术上正确的值。
比如:调用typeof null
会返回"object"
。
原因:特殊值 null
被认为是一个空的对象引用。
问题:为什么使用typeof
操作符检测函数时,返回的不是"object"
,而是"function"
?
答案:从技术角度讲,函数在 ECMAScript
中是对象,而不是一种数据类型。但是函数也需要有一些特殊的属性。
因此,通过 typeof
操作符来区分函数和其他对象是有必要的。
3.4.2 Undefined类型
该类型只有一个值,即特殊的 undefined
值。
在使用var
关键字声明变量时,如果未对该变量进行初始化(即赋初始值)时,该变量的值就是 undefined
。
比如:
var message;
alert( message == undefined ); //true
代码分析:
(1) 上面的代码只是声明了变量message
,但并未对其进行初始化。
(2)比较这个变量与 undefined
字面量的值,结果表明它们是相等的。
其实,下面这两种写法等价:
var message;
var message = undefined; //显式的初始化了变量message
代码分析:
没必要这么做,因为未经初始化的变量的值默认就是undefined
,无需自己设置。
注意:
(1)一般而言,不存在将一个变量显式地设置为undefined
值的情况。
(2)字面量值 undefined
产生的主要目的是:用于比较。
(3)在ECMA-262
第3
版之前的版本中,并没有规定这个值。
(4)第3
版中引入 undefined
这个值,是为了正式区分 空对象指针(会返回null
)与未经初始化的变量(会返回undefined
)。
3.4.3 Null类型
Null
类型也只有一个值,这个特殊值是 null
。它是第二个只有一个值的数据类型。上一个是 Undefined
类型。
从逻辑角度看,null
值表示一个空对象指针。所以,在使用 typeof
操作符检测 null
值时会返回"object"
。
如下所示:
var car = null;
console.log( typeof car); //"object"
说明:如果定义的变量准备在将来用于保存对象,那么最好将该变量初始化为null
值,而不是其他值。
原因:这样一来,只要直接检查 null
值就可以知道相应的变量是否已经保存了一个对象的引用。
如下所示:
if ( car != null){
//对car对象执行某些操作
}
注意:
(1)实际上 undefined
值是派生自null
值的,因为先有的 null
,然后才有的undefined
。
所以,ECMA-262
规定对它们的相等性测试,要返回true
。即:
console.log( undefined == null ); //true
(2)虽然它们的关系很特殊,但是它们的用途完全不同。
区别:
- 任何情况下,都没有必要把一个变量的值显式地设置为
undefined
;【该规则不适用于null
】 - 只要保存对象的变量还没有真正的保存对象之前,就应该明确地让该变量的值保存为
null
。
这样做的目的是:
- 体现 null
本身的作用,即作为一个空对象指针。
- 有助于进一步区分 null
和 undefined
。
3.4.4 Boolean类型
该类型有两个字面值:true
和false
。
Boolean
类型是 ECMAScript
中使用最多的一种类型。
一定要注意:
(1)true
和 false
这两个值与数字值的0
和1
不是一回事,不要混淆了。
因此,true
不一定 等于1
,而 false
不一定等于0
。
(2)Boolean
类型的字面值true
和false
是区分大小写的,只能用小写来表示。
(3)ECMAScript
中所有类型的值都有 与这两个 Boolean
值等价的值。
提示:
要将一个值转换为其对应的 Boolean
值,可以调用转型函数 Boolean()
。
如:
var str = "hello world";
var strAsBoolean = Boolean(str);
代码分析:
字符串str
被转换成了一个Boolean
值,该值被保存在 strAsBoolean
变量中。
说明:
(1)可以对任何数据类型的值调用Boolean()
函数,而且总会返回一个Boolean
值。
(2)至于返回的值是 true
还是false
,取决于要转换值的数据类型以及它的实际值。
各种数据类型对应的转换规则
数据类型 | 转换为true的值 | 转化为false的值 |
---|---|---|
Boolean | true | false |
Undefined | 不适用 | undefined |
Number | 任何非0数字值(包括无穷大) | 0和NaN |
String | 任何非空字符串 | “”(空字符串) |
Object | 任何对象 | null |
说明:
以上的转换规则,对理解流控制语句(如if
语句),自动执行相应的条件分支非常重要。
比如:
var str = "hello world";
if( str ){
alert("Value is true");
}
代码分析:
(1)字符串str
在if
的条件判断中,被自动转换成了对应的 Boolean
值(true)
。
(2)由于存在这种自动执行的 Boolean
转换,因此确切地知道在流控制语句中使用的是什么变量至关重要。
(3)错误的使用一个对象,而不是一个 Boolean
值,就有可能彻底改变应用程序的流程。
3.4.5 Number类型
Number
类型应该是 ECMAScript
中最令人关注的数据类型了。
为了支持各种数据类型,ECMA-262
定义了不同的数值字面量格式。
最基本的数值字面量格式是十进制整数。
除此之外,整数还可以通过八进制(以8为基数)
或十六进制(以16为基数)
的字面值来表示。
八进制:
(1)八进制字面量的第一位必须是0
,后面跟八进制数字序列(0~7)
。
(2)如果字面值中的数值超出了范围,前导0
将会被忽略,前导0
后面的数值将被当做十进制数值解析。
(3)八进制字面量在严格模式下是无效的,会导致支持的JavaScript
引擎抛出错误。
示例:
var octalNum1 = 070; //八进制的56
var octalNum1 = 079; //无效的八进制数值——会解析为十进制的79
var octalNum1 = 08; //无效的八进制数值——会解析为十进制的8
十六进制:
(1)十六进制字面值的前两位必须是0x
,后面跟任何十六进制数字(0~9及A~F)
。
(2)其中,字母A~F
既可以大写也可以小写。
示例:
var hexNum1 = 0xA; //十六进制的10
var hexNum1 = 0x1f; //十六进制的31
注意:
在进行算术计算时,所有以八进制和十六进制表示的数值最终都将被转换成十进制数值。
提示:
正零(+0)
和负零(-0)
被认为相等。
1.浮点数值
表示该数值中必须包含一个小数点,并且小数点后面至少有一位数字。
【不推荐的另外一种写法】:对于0.?
的小数,可以省略小数点前面的整数0
。
示例:
var floatNum1 = 1.1;
var floatNum2 = 0.1;
var floatNum3 = .1; //相当于0.1,有效但不推荐
说明:
(1)如果小数点后面没有跟任何数字,那么这个数值就将被作为整数值来保存。
(2)如果浮点数值本身表示的就是一个整数(如1.0
),那么这个数值也会被转换为整数。
示例:
var floatNum1 = 1.; //小数点后面没数字——被解析为整数值1
var floatNum2 = 10.0; //整数——解析为10
对于那些极大或者极小的数值,可以用e
表示法(即科学计数法)表示的浮点数值表示。
e表示法表示的数值 = e前面的数值 * 10的指数次幂。
写法:
前面一个数值(整数或者浮点数),中间是一个大写或者小写的字母e
,后面的值是指数,表示10
的多少次方。(指数可以为负数)
示例:
var floatNum = 3.125e7; //等于3.125*10^7 = 31250000
分析:
e
表示法的实际含义就是:3.125
乘以10
的7
次方。
2.数值范围
(1)ECMAScript
能够表示的最小数值保存在 Number.MIN_VALUE
中。
(2)ECMAScript
能够表示的最大数值保存在 Number.MAX_VALUE
中。
说明:
(1)如果某次计算的结果得到一个超出 JavaScript
数值范围的值,那么这个数值将被自动转换成特殊的Infinity
值。(注:正数除以 0
返回Infinity
,负数除以 0
返回-Infinity
)
(2)Infinity
是一个无法参与计算的数值。
(3)isFinite()
函数可以判断一个数值是不是有穷的,即是否位于最小和最大的数值之间。
示例:
isFinite( 5/0 ) //false,因为 Number(5/0) 会返回 Infinity
单词解释:
finite 详情> 英 [ˈfaɪnaɪt] adj.有穷的;有限的
infinity 详情> 英 [ɪnˈfɪnəti] n.无穷大;无限
3.NaN
NaN
,即非数值(Not a Number)
,它是一个特殊的数值。
它用来表示一个本来要返回数值的操作数未返回数值的情况(这样就不会抛出错误了)。
区别:
(1)在其他编程语言中,任何数值除以0
都会导致错误,从而停止代码执行。
(2)但是在ECMAScript
中,实际上,只有0
除以0
才会返回NaN
,正数除以0
返回 Infinity
,负数除以0
返回 -Infinity
。
NaN
的两个非同寻常的特点:
(1)任何涉及NaN
的操作都会返回NaN
。如:console.log( NaN/10 ) //NaN
(2)NaN
与任何值都不相等,包括它本身。如:console.log( NaN = NaN ); //false
然后,针对NaN
的特点,ECMAScript
定义了isNaN()
函数。
isNaN()
函数说明:
该函数接收一个参数,该参数可以是任何类型的。
isNaN()
函数的作用:帮我们确定这个参数是否“不是数值”。
过程:isNaN()
在接收到一个值之后,会尝试将这个值转换为数值。
规则:
- 如果接收的值能转换为数值,就返回
false
; - 如果接收的值不能转换为数值,都会返回
true
。
注意:某些不是数值的值,isNaN()
函数会直接转换为数值,如字符串"10"
或Boolean
值。
示例:
console.log( isNaN( NaN ) ); //true(NaN本身)
console.log( isNaN( 10 ) ); //false(10是一个数值)
console.log( isNaN( "10" ) ); //false(字符串"10"可以被转换成数值10)
console.log( isNaN( "blue" ) ); //true(字符串"blue"不能被转换成数值)
console.log( isNaN( true ) ); //false(Boolean值 true 可以被转换成数值1)
console.log( isNaN( "" ) ); //false( 空字符串会被Number()转型函数转换为0,0是一个数值 )
提示:isNaN()
方法也适用于对象。
isNaN()
函数在对象中的用法:
- 在基于对象调用
isNaN()
函数时,会首先调用对象的valueOf()
方法,然后确定该方法返回的值是否可以转换为数值; - 如果不能返回数值,则基于这个返回值再调用
toString()
方法,再测试返回值。
注:这个过程,也是ECMAScript
中内置函数和操作符的一般执行流程。
4.数值转换
有3
个函数可以把非数值转换为数值:Number()、parseInt()、parseFloat()
。
说明:
(1)转型函数 Number()
可以用于任何数据类型。
(2)parseInt()
和parseFloat()
函数专门用于把字符串转换成数值。
转型函数 Number()
的转换规则:
(1)对于Boolean
值,转换后,true
返回1
,false
返回0
。
(2)对于数字
值,只是简单的传入和返回,原样输出。
(3)对于 null
值,返回 0
。
(4)对于undefined
值,返回 NaN
。
(5)对于字符串,遵循下列规则:
①若字符串中只包含数字(包括带正负号的情况),则将其转化为10
进制数值。(注意:会忽略前导0
)
Number( "123"); //123
Number( "000011"); //11
②若字符串中包含有效的浮点格式,如"1.1"
,则将其转换为对应的浮点数值。(同样会忽略前导0
)
Number( "1.1"); //1.1
Number( "000.11"); //0.11
③若字符串中包含有效的16
进制格式,如"0xf"
,则将其转化为相同大小的10
进制整数值。
Number( "0xf"); //15
④如果字符串是空的,即""
,则将其转换为0
。
Number( ""); //0,空字符串被转换为0
⑤如果字符串中包含除上述格式之外的字符,则将其转换为 NaN
。
Number( "abc"); //NaN,因为其中不包含任何有意义的数字值。
(6)对于对象,则会调用对象的valueOf()
方法,然后依次按照前面的规则,转换返回的值。
如果转换的结果是NaN
,则调用对象的toString()
方法,然后再次按照前面的规则,转换返回的字符串值。
提示:
因为Number()
函数在转换字符串时比较复杂而且不够合理,所以在处理整数时更常用的是使用 parseInt()
函数。
parseInt()函数的转换规则:【从左到右进行判断】
(1)如果字符串中的第一个字符不是数字字符或者符号,parseInt()
会自动终止解析并且返回NaN
;
parseInt(""); //NaN
parseInt("abc123"); //NaN
(2)如果字符串中的第一个字符是数字字符,则会继续向后解析,直到解析完所有的字符或者遇到非数字字符为止。
parseInt("100px"); //100
此外,如果字符串中的第一个字符是数字字符,parseInt()
能识别出各种整数格式(10
进制、8
进制和16
进制)。
①如果字符串以"0x"
开头且后面跟数字字符,就会将该字符串当作一个16
进制的整数。
parseInt("0xA"); //10(16进制数)
parseInt("0xf"); //15(16进制数)
②如果字符串以"0"
开头且后面跟数字字符,就会将该字符串当作一个8
进制的整数。
parseInt("070"); //56(8进制数)
简而言之就是,parseInt()
函数提取的是“首字符为数字的任意字符串”
中的数字。
仅作为了解的知识:
在使用parseInt()
解析像8
进制字面量的字符串时,ECMAScript 3
和5
存在分歧。
例如:
var num = parseInt("070");//ECMAScript 3 认为是 56(八进制);而ECMAScript 5 认为是 70(十进制)
原因:
①在ECMAScript 3 JavaScript
引擎中,"070"
被当作是8
进制的字面量进行解析。
②而在ECMAScript 5 JavaScript
引擎中,parseInt()
已经不具备解析8
进制的能力,所以前导的0
会被认为无效。
解决方法:
为了消除该函数可能导致的上述问题,应该为parseInt()
函数提供第2
个参数:转换时使用的基数。
(基数,就是指多少进制)
说明:
如果你知道要解析的值是16
进制格式的字符串,就可以指定基数16
作为第2
个参数,可以保证得到正确的结果。
比如:var num = parseInt("0xAF",16); //该值按照16进制进行解析,结果为175
分析:
第二个参数传入了基数,已经明确的告诉了parseInt()
要解析一个16
进制格式的字符串。
注意:
(1)指定基数会影响到转换的输出结果。
(2)不指定基数或者第二个参数的值为0
,意味着让parseInt()
决定如何解析输入的字符串。
- 因此,为了避免错误的解析,建议任何情况下都要明确地指定基数。
- 多数情况下,我们要解析的都是
10
进制数,所以始终将10
作为第2
个参数是非常必要的。
parseFloat()
与parseInt()
函数类似:
它也是从第一个字符开始解析,一直解析到字符串末尾,或者遇到一个无效的浮点数字字符为止。
注意:
(1)字符串中的第一个小数点是有效的,第二个就是无效的,所以它后面的字符串将被忽略。
parseFloat("22.34.5"); //22.34
(2)parseFloat()
可以识别所有的浮点数值格式。但是对于16
进制格式的字符串,始终会被转换成0
。
parseFloat("0xa");//0
(3)因为parseFloat()
方法始终都会忽略前导的0
。;
parseFloat("0000070");//70
(4)parseFloat()
方法只解析10
进制值,因为它没有第2
个参数指定基数的用法。
(5)如果字符串包含的是一个可解析为整数的数,parseFloat()
方法会返回整数。
用法示例:
parseFloat("100px"); //100
parseFloat("12.34.56"); //12.34
parseFloat("0xA"); //0
parseFloat("22"); //22
parseFloat("10.5"); //10.5
parseFloat("09.85"); //9.85
3.4.6 String类型
String
类型用于表示 由0
个或多个 16
位Unicode
字符组成的 字符序列,即字符串。(了解就行)
- 字符串可以由双引号
("")
或单引号('')
表示。 - 这两种表示字符串的语法形式完全相同。但是左右的括号必须相匹配。
示例:
var firstName = "fly";
var lastName = 'monkey';
问题:什么是Unicode
字符?
Unicode
是 国际组织制定的 可以容纳世界上所有文字和符号的
字符编码方案。
答案:为了统一所有文字的编码,Unicode
应运而生。所以Unicode
也叫统一码。
Unicode
把所有语言都统一到一套编码里,这样就不会再有乱码问题了。Unicode
通常用两个字节表示一个字符,原有的英文编码从单字节变成了双字节。
起源:
(1)计算机只能处理数字,不能处理文本,如果要处理文本必须先将文本转为数字才行。
(2)而最早的计算机在设计时默认采用了8
个比特(bit)
作为一个字节(byte)
,所以一个
字节(byte)
所能表示的最大整数就是255
。(二进制11111111 = 十进制255)
(3)0 - 255
被用来表示大小写英文字母、数字和一些符号,这个编码表被称为ASCII
编码。
(4)但是,如果要表示中文,一个字节显然是不够的,至少需要两个字节,而且还不能和ASCII码冲突。
所以,中国制定了GB2312
编码,用来把中文编进去。
名词解释:
- 比特:
(1)bit
,计算机的专业术语,是信息量的最小度量单位。
(2)同时,bit
也是二进制数字中的位
,二进制数的1
位所包含的信息就是1 bit
。 - 位:
(1)在二进制数系统中,每个0
或1
就是一个位(bit)
。
(2)位是数据存储的最小单位。其中8 bit
就称为一个字节(Byte)
。
1.字符字面量
字符字面量,也叫转义序列,用来表示非打印字符,或者具有其他用途的字符。
字面量 | 含义 |
---|---|
\n | 换行符 |
\t | 制表符 |
\b | 空格 |
\r | 回车 |
\f | 进纸 |
\\ | 反斜杠(\) ,本意为转义字符,在需要将反斜杠(\) 作为字符输出时使用。 |
\' | 单引号(') ,在需要将单引号作为字符输出时使用。 |
\" | 双引号(") ,在需要将双引号作为字符输出时使用。 |
\xnn | 以十六进制代码nn 表示的一个字符(其中,n 的取值为0~9及A~F )。如:\x41 表示"A" 。 |
\unnn | 以十六进制代码nnnn 表示的一个Unicode 字符(其中,n的取值为0~9及A~F)。如:\u03a3 表示希腊字符sigma"∑" 。 |
说明:
这些字符字面量可以出现在字符串中的任意位置,而且也将根据它们各自的含义被作为一个字符来解析。
示例:
var text = "这是字母sigma:\u03a3";
console.log( text ); //输出"这是字母sigma:Σ"
console.log( text.length ); //输出11
分析:
(1)该变量text
中有11
个字符。其中,6
个字符长的转义序列表示1
个字符。
(2)任何字符串的长度都可以通过访问字符串的length
属性获取。
2.字符串的特点
ECMAScript
中的字符串是不可变的。也就是说,字符串一旦创建,它们的值就不能改变。 (并不是变量的值不可变)
说明:
如果要改变某个变量保存的字符串,首先要销毁原来的字符串,然后再用另外一个包含新值的字符串填充该变量。
示例:
var str = "Java";
str = str + "Script";
分析:
(1)变量 str
开始时包含字符串"Java"
。
(2)第二行代码将变量 str
的值重新定义了一番,现在的值是"Java"
和"Script"
的组合,即"JavaScript"
。
问题:该过程是如何实现的呢?
答案:
(1)首先创建一个能容纳10
个字符的新字符串;
(2)然后在这个字符串中填充"Java"
和"Script"
;
(3)最后一步就是销毁原来的字符串"Java"
和"Script"
。因为这两个字符串已经没用了。
注:整个过程是在后台发生的,这也是在某些旧版本的浏览器中拼接字符串时速度很慢的原因所在。
3.转换为字符串
一个值转换为字符串有两种方式:
(1)使用加号操作符(+
)。将要转换的值用+
与空字符串("")
相加即可自动转换。
(2)使用toString()
方法。(几乎每个值都有该方法,除了null
和undefined
值;该方法唯一要做的就是返回相应值的字符串表现)
示例:
var age = 11;
var ageAsString = age.toString();
console.log(ageAsString); //返回字符串"11"
var flag = true;
var flagAsString = flag.toString();
console.log(flagAsString); //返回字符串"true"
var str = "fly";
var strAsString = str.toString();
console.log(strAsString); //返回字符串"str"
说明:
(1)数值、布尔值、对象和字符串值都有toString()
方法。但是null
和 undefined
值没有该方法。
(2)每一个字符串都有一个toString()
方法,调用该方法会返回字符串的一个副本。
(3)大多数情况下,调用 toString()
方法不必传参数。
(4)特殊情况:在调用数值的 toString()
方法时,可以传递一个参数:用来输出数值的基数。
(5)默认情况下,toString()
方法 以十进制格式返回数值的字符串表示。
提示:
通过传递基数,数值调用 toString()
方法可以输出任意有效的进制格式(如8,10,16
进制等)表示的字符串值。
示例:
var num = 10; //均返回了该数值相应的字符串表示。
console.log( num.toString() ); // "10"
console.log( num.toString(2) ); // "1010"
console.log( num.toString(8) ); // "12"
console.log( num.toString(10) ); // "10"
console.log( num.toString(16) ); // "a"
分析:
(1)通过改变基数,toString()
方法会改变输出的值。
(2)数值10
根据方法内传递的基数的不同,可以在输出时被转换成不同数值格式的字符串表示。
注意:
toString()
方法默认无参数,因此默认按照基数10
输出。
提示:
- 如果不知道要转换的值是否为
null
或者undefined
,可以使用转型函数String()
。 - 该函数与转型函数
Number()
的作用类似,它能将任何类型的值转换为字符串。
String()
方法的转换规则:
(1)使用前会先调用该值的 toString()
方法并返回相应的结果。(如果所要转换的值有该方法的话)
(2)因为null
和 undefined
值都没有 toString()
方法。所以调用String()
方法会返回它们相对应的字面量值。
即:
- 值为
null
,返回"null"
; - 值为
undefined
,返回"undefined"
。
说明:String()
方法的本质还是调用 toString()
方法来实现的。
示例:
var value1 = 10; //数值
var value2 = true; //布尔值
var value3 = null; //null值
var value4; //undefined值
console.log( String(value1) ); // "10"
console.log( String(value2) ); // "true"
console.log( String(value3) ); // "null"
console.log( String(value4) ); // "undefined"
分析:
(1)数值和布尔值的转换结果与调用toString()
方法得到的结果相同。
(2)因为null
和 undefined
值都没有toString()
方法,所以调用String()
方法就返回了这两个值的字面量。
3.4.7 Object类型
ECMAScript
中的对象其实就是一组数据和功能的集合。
对象可以通过执行new
操作符,后面跟要创建的对象类型的名称来创建。
如:
var obj = new Object();
而创建Object
类型的实例,并且为其添加属性或方法,就可以创建自定义对象。
如:
var obj = new Object(); //创建了Object类型的一个实例
obj.name = "fly"; //为该对象的实例添加了name属性
obj.age = 20; //为该对象的实例添加了age属性
console.log(obj); //Object {name: "fly", age: 20}
注意:
(1)该方法与Java
中创建对象的语法相似。
(2)如果不给构造函数传递参数,则可以省略构造函数后面的那对圆括号。【不推荐的做法】
像上面的这种情况就可以省略那对圆括号,即:
var obj = new Object; //有效,但不推荐省略圆括号
我们要知道:仅仅创建Object
的实例并没有什么用处。
关键是我们要理解一个重要的思想:
在ECMAScrit
中,Object
类型是所有它的实例的基础。(就像Java
中的java.lang.Object
对象一样,它是其他所有类的鼻祖)
换句话说,Object
类型所具有的任何属性和方法,也同样存在于更具体的对象中。
Object
的每个实例都具有下列属性和方法。
(1)constructor
:保存着用于创建当前对象的函数,即构造函数。对前面的例子而言,Object()
就是构造函数。
(2)hasOwnProperty(propertyName)
:用于检查给定的属性在当前对象实例中(而不是在实例的原型中)是否存在。其中,作为参数的属性名必须以字符串的形式指定。如:obj.hasOwnProperty("name");
(3)isPrototypeOf(object)
:用于检查传入的对象是否是传入对象的原型。(后面会讲到)
(4)propertyIsEnumberable(propertyName)
:用于检查给定的属性是否能够使用for-in语句来枚举。作为参数的属性名必须以字符串形式指定。(后面会讲到)
(5)toLocaleString()
:返回对象的字符串表示。该字符串与执行环境的地区对应。
(6)toString()
:返回对象的字符串表示。
(7)valueOf()
:返回对象的字符串、数值或布尔值表示。通常与toString()
方法的返回值相同。
提示:
(1)由于在ECMAScript
中,Object
是所有对象的基础,因此所有对象都具有这些基本的属性和方法。
(2)ECMA-262
中对象的行为不一定适用于JavaScript
中的其他对象。
注意:
(1)浏览器中的对象属于宿主对象,如BOM
和DOM
中的对象。它们是由宿主实现提供和定义的。
(2)ECMA-262
不负责定义宿主对象,所以宿主对象可能会也可能不会继承Object
。