第三章 基本概念
3.1 语法
- ECMAScript大量借鉴C、Java、Perl语法
3.1.1 区分大小写
- 一切(变量、函数名、操作符)区分大小写
- typeof为关键字不可做函数名
- 但typeOf可以做函数名
3.1.2 标识符
- 首字符必须是 字母、下划线或$
- 其他字符可以是 字母、下划线、数字、$
- ECMAScript采用驼峰大小写格式
- 不能使用关键字、保留字、true、false、null
myCar
doSometingImportant
3.1.3 注释
- 单行注释
// 单行注释
- 块级注释
/*
* 多行
* 注释
*/
3.1.4 严格模式
"use strict";
3.1.5 语句
- ECMAScript语句以分号结尾
- 不带分号也有效,不过不推荐
- 带分号的好处
- 可以避免压缩错误
- 解析器不用推测哪里插入分号,提高性能
3.2 关键字和保留字
- 具有特殊用途的字符,不能用作标识符
- 关键字
break、else、new、var、 case、 finally 、 return、 void 、 catch 、for 、switch 、 while 、 continue、 function 、this 、 with 、default 、 if 、 throw 、 delete 、 in 、 try 、do 、 instranceof、 typeof
- 保留字(将来可能启用)
abstract 、 enum 、int 、 short 、 boolean 、export 、interface、 static、 byte 、extends 、 long 、 super 、 char 、 final 、native 、synchronized 、 class 、float 、 package 、throws 、 const 、goto 、private 、transient 、 debugger 、 implements 、protected 、 volatile 、 double 、import 、public
- ECMA-262第5版把在非严格模式下运行时的保留字缩减为下列
class enum extends super const export import
- 在严格模式下,ECMA-262第5版还对以下保留字施加了限制:
implements package public interface private static let protected yield
3.3 变量
var message = "hi",
found = false,
age = 29;
3.4 数据类型
- ECMAScript中有 5中基本数据类型(简单数据类型)
- Undefined
- Null
- Boolean
- String
- Number
- ECMAScript中有 1种复杂数据类型
- Object
3.4.1 typeof 操作符(检测给定变量数据类型),返回情形:
- undefined(未定义)
- boolean(布尔值)
- string(字符串)
- number(数值)
- object(对象或null)
- function(函数)
3.4.2 Undefined类型
var message; //undefined
alert(typeof message); //undefined
alert(typeof age); //undefined age未初始化,不推荐
alert(message); //undefined
alert(age); //报错
3.4.3 Null类型
- 表示一个空对象的指针
typeof null == object
- 如果变量将来用于保存对象,最好初始化为null
var man = null;
man = {
name: 'Tom',
age: 18
}
if(man != null){
console.log(man.name);
}
3.4.4 Boolean类型
- true和false (其他有大小写的不是)
- 所有ECMAScript所有数据类型的值都有与Boolean等价的值
数据类型 | 转换为true | 转换为false |
---|---|---|
Boolean | true | false |
String | 非空 | 空字符串 |
Number | 任何非零数值 | 0或NaN |
Undefined | n/a(不适用) | undefineds |
Object | 任何对象 | null |
3.4.5 Number类型
- 整数(有符号整数、无符号整数)
- 31位表示数值,第32位表示符号,0正数,1负数
- 数值范围从 -2147483648 到 2147483647
- 正数以真二进制形式存储 负数以二进制补码存储
- 所有整数字面量默认存储为有符号整数。只有 ECMAScript 的位运算符才能创建无符号整数
- 浮点数值(其他语言称为双精度数值)
- 八进制
- 首位为0,其他数字范围(0~7)
- 如果字面值中的数值超出范围,则忽略前导0,做十进制处理
var num1 = 070; //八进制56 var num2 = 079; //八进制无效 解析为79
- 十六进制
- 首位0x,其他数字范围(0-9 A-F)
- 拓展3.4.5 进制数转换算法
浮点数值
- ECMAScript:整数默认显示21位,小数默认显示6位,超范围使用科学计数
var a = 100000000000000000000; //100000000000000000000 var b = 1000000000000000000000; //1e21 var c = 0.000001; //0.000001 var d = 0.0000001; //1e-7
- 舍入误差
0.1 + 0.2 = 0.30000000000000004 console.log(0.1 + 0.2 !=0.3) //true
- 原因:计算器使用二进制计算,数值转换时出现无限循环
对于无理数,双精度浮点数小数部分最多支持52位0.1==》0.1.toString(2)==》0.0001100110011(无限循环..) 0.2==》0.2.toString(2)==》0.0011001100110(无限循环..)
所以相加后,得到0.0100110011001100110011001100110011001100110011001100
对应十进制的0.30000000000000004
- 解决方案1 toFixed
parseFloat((0.1 + 0.2).toFixed(2)) === 0.30
- 解决方案2 升级(乘以10^n)为整数,计算后降级(除以 10^n)
(0.1*10 + 0.2*10) / 10 == 0.3 //true
- 举例
/* * @description 加法函数,用来得到精确的加法结果 * @param {Num} arg1 第一个加数 * @param {Num} arg2 第二个加数 * @param {Num} d 要保留的小数位数(可选) * @example add(0.1,0.2,2) * @return {Num} 两数相加的结果 */ function add(arg1, arg2) { arg1 = arg1.toString(), arg2 = arg2.toString(); var arg1Arr = arg1.split('.'), arg2Arr = arg2.split('.'), d1 = arg1Arr.length == 2 ? arg1Arr[1] : '', d2 = arg2Arr.length == 2 ? arg2Arr[1] : ''; var maxLen = Math.max(d1,d2), m = Math.pow(10, maxLen); var result = Number(((arg1 * m + arg2 * m) / m).toFixed(maxLen)), d = arguments[2]; return typeof d === 'number' ? Number((result).toFixed(d)) : result; }
数值范围
- ECMAScript规定
- 能表示的最小数保存在Number.MIN_VALUE中 (大多数浏览器5e-324)
- 能表示的最大数保存在Number.MAX_VALUE中(大多数浏览器1.7976931348623157e+308)
- 如果某次计算超过JS数值范围,则数值自动转为特殊的Infinity值(Infinity正无穷 -Infinity负无穷)
- 可以使用isFinite()函数 区间内返回true
var result = Number.MAX_VALUE + Number.MAX_VALUE; console.log(result); //Infinity console.log(isFinite(result)); //false
- Number.NEGATIVE_INFINITY 表示正Infinity
- Number.POSITIVE_INFINITY 表示负Infinity
NaN 非数值
- 任何涉及NaN的操作,都会返回NaN
- NaN != NaN
- isNaN()函数
console.log(isNaN(NaN)); //true console.log(isNaN(10)); //false console.log(isNaN("10")); //false console.log(isNaN("blue")); //true console.log(isNaN(true)); //false
数值转换
- 非数值转数值函数:Number()、parseInt()、parseFloat()
- Number()
- Boolean: true->1 false->0
- 数值: 1->1 -1->-1
- null: ->0
- undefined: -> NaN
- 字符串
- 忽略前导0:'011'->11
- 浮点格式: '1.1'->1.1
- 十六进制: '0xf'->15
- 空:''->0
- 其他:-> NaN
- 对象(调用对象valueOf()转换,如果为NaN则调用对象toString()转换):
var a={age:'18'}; Number(a.age)=18
Number('Hello World'); //NaN Number('00011'); //11
- 与parseInt不同
Number(true); //1 Number(' '); //0
- parseInt() 整数处理
- 相比Number好处
- 自动忽略前导空格
- 空字符串返回NaN
- 可以忽略数字后的非数字字符
parseInt('1234blue'); //1234 parseInt(''); //NaN parseInt(true); //NaN parseInt('0xA'); //10 parseInt('22.5'); //22 parseInt('070'); //56 parseInt('70'); //70 parseInt('0xf'); //15
- 注意:ES3可以解析八进制,ES5无自动解析八进制能力,所以需要明确基数
parseInt('070'); //15 ES3 parseInt('070'); //70 ES5 parseInt('070',8); //56 ES3+ES5
- 有了基数,可以忽略进制前导位
parseInt('70',8); //56 ES3+ES5 parseInt('F',16); //15 ES3+ES5 parseInt('F'); //NaN
- 基数示例
parseInt('10',2); //2 parseInt('10',8); //8 parseInt('10',10); //10 parseInt('10',16); //16
- 相比Number好处
- parseFloat() 浮点数处理函数(与parseInt类似)
- 区别1:第一个小数点有效,第二个及后面无效
- 区别2:始终忽略前导0,只解析十进制。
parseFloat('123blue'); //123 parseFloat('0xA'); //0 parseFloat('22.5'); //22.5 parseFloat('22.34.5'); //22.34 parseFloat('0908.5'); //908.5 parseFloat('3.125e7'); //31250000
3.4.6 String类型
- 表示由零或多个16位Unicode字符组成的字符序列
- 单引号或双引号表示
字符字面量
- 特殊字符,也叫转义序列
字面量 | 含义 |
---|---|
\n | 换行 |
\r | 回车 |
\t | 制表 |
\b | 空格 |
\ | 斜杠 |
' | 单引号 |
" | 双引号 |
\xnn \unnn | \x41表示A \u03a3表示Σ |
- 转换位字符串
- 方法1:toString() (不支持undefined和null值调用)
var age = 11; age.toString(); //"11" var found = true; found.toString(); //"true" //基数 var num = 10; num.toString(); //"10" num.toString(2); //"1010" num.toString(8); //"12" num.toString(10); //10"" num.toString(16); //"a"
- 方法2:String() (支持undefined和null值调用)
- 如果值由toString()方法,则执行
- 如果值是null,返回"null"
- 如果值是undefined,返回"undefined"
var value; console.log(String(10)); //"10" console.log(String(true)); //"true" console.log(String(null)); //"null" console.log(String(value)); //"undefined"
- 把某个值转字符串 与
""
相加
3.4.7 Object类型
- var obj = new Object();
- Object每个实例都有下列属性和方法
- Constructor: 保存用于创建当前对象的函数
- hasOwnProperty(propertyName): 对象实例中是否存在属性propertyName
- isPrototypeOf(object): 检查对象是否是object的原型
- propertyIsEnumerable(propertyName): 检查给定属性书否能枚举
- toLocalString(): 返回对象的字符串表示 该字符串与执行环境地区对应
- toString(): 返回对象的字符串表示
- valueOf():返回对象的字符串、数值、布尔值表示
function Person(name,age,sex){ this.name = name; this.age = age; this.sex = sex; this.getInfo = function(){ return 'Name:'+this.name+',Age:'+this.age; } } var p = new Person('Tom',18); p.getInfo(); //"Name:Tom,Age:18"
3.5 操作符
- ECMAScript描述了一组用于操作数据值的操作符
- 包括 算术操作符、位操作符、关系操作符、相等操作符
3.5.1 一元操作符
递加递减
var age = 29;
++age; //相当于age=age+1 30
var num1 = 2;
var num2 = 20;
var num3 = --num1+num2; //21
var num3 = num1+num2; //21
var num1 = 2;
var num2 = 20;
var num3 = num1--+num2; //22
var num3 = num1+num2; //21
- 适用任何值
- 无有效数字字符串:NaN
- false:先转为0在计算,例如
var a = false; --a; //-1
- true:先转为1在计算
- 浮点数
- 对象:调用对象valueOf()进行计算 -> 如果NaN -> 调用toString()进行计算
var s1 = "2"; //s1++ 3
var s2 = "z"; //s2++ NaN
var b = false; //b++ 1
var f = 1.1; //f-- 0.10000000000000009
var o = {
valueOf: function(){
return -1;
}
}; //o-- -2
一元加 一元减
- 类似Number()处理函数
- 一元加
var s1 = "01"; //s1=+s1; 1
var s2 = "1.1"; //s2=+s2 1.1
var s3 = "z"; //s3=+s3 NaN
var b = false; //b=+b 0
var f = 1.1; //f=+f 1.1
var o = {
valueOf: function(){
return -1;
}
}; //o=+o -1
- 一元减 主要用于表示负数
3.5.2 位操作符
- 对于有符号整数,32位中前31位表示整数,第32位表示符号位(0正数 1负数)
- 正数 以纯二进制存储
18 //00000000000000000000000000010010
- 负数 以二进制补码存储 补码算法如下
- 获取绝对值的二进制码
- 获取反码
- 补码= 反码+1
-18 00000000000000000000000000010010 //绝对值二进制码 11111111111111111111111111101101 //反码 11111111111111111111111111101110 //补码=反码+1
- 对于无符号整数,只能表示正数,第32位不在表示符号
- 拓展3.5.2 原码、反码、补码
按位非(NOT) ~
- 按数值的原码处理
- 用~表示,就是返回数值的反码
- 规律:
- 正数:数值的负值-1
- 负数:数值的正值+1
var num1 = 25; // 0001 1001 ~num1; // 1110 0110(补码) -> 1110 0101(反码) -> 1001 1010(原码) = -26
按位与(AND) &
25 & 3 = 0001 1001 & 0000 0011 = 0001 = 1
按位或(OR) |
25 | 3 = 0001 1001 | 0000 0011 = 0001 1011 = 27
//注意不是 ||
25 || 3 = 25
按位异或(XOR) ^
- 不同时为1 相同时为0
25 ^ 3 = 0001 1001 ^ 0000 0011 = 11010 = 26
左移 <<
- 符号位保持不变
2 << 5 = 0000 0010 << 5 = 0100 0000 = 64
-2 << 5 = 1000 0010 << 5 = 1100 0000 = -64
有符号位右移 >>
- 符号位保持不变
64 >> 5 = 0100 0000 >> 5 = 0000 0010 = 2
-64 >> 5 = 1100 0000 >> 1000 0010 = -2
无符号位右移 >>>
-64 >>> 5 = 134217726
3.5.3 布尔操作符
逻辑非 !
!{} //false
!undefined //true
!null //true
!false //true
!"blue" //false
!0 //true
!NaN //true
!'' //true
!123 //false
!!"blue" //true
!!0 //false
!!NaN //false
!!'' //false
!!123 //true
逻辑与 &&
var found = true;
var result = found && something; //发生错误
var found = false;
var result = found && something; //false 可执行,警告something未定义
3.5.4 乘性操作符
- ECMAScript定义了3个乘性操作符:乘法* 除法/ 求余%
3.5.5 加性操作符
- 加法+
var num1 = 3,num2 = 2;
var mess = "The res is " + num1 + num2; //The res is 32
var mess2 = "The res is " + (num1 + num2); //The res is 5
- 减法-
5 - true //4
NaN - 1 //NaN
5 - 3 //2
5 - "" //5
5 - "2" //3
5 - null //5
3.5.6 关系操作符
- < > <= >=
"Blue" < "alpha" //true 都为字符串时,比较字符串对应编码值
"Blue".toLowerCase() < "alpha".toLowerCase() //false
"23" < "3" //true
"23" < 3 //false 一个为数值,则将另一个操作数转为数值比较
//转为NaN时,比较都为false
"a" < 3 //false
"a" >=3 //false
3.5.7 相等操作符
相等和不相等 == !=
- 先转换再比较
- boolean和数值比较 false->0 true->1
- 字符串和数值比较 字符串->数值
- 对象 valueOf()
- null和undefined相等
- NaN 不等于 NaN
null == undefined //true "NaN" == NaN //false 5 == NaN //false NaN == NaN //false NaN != NaN //true false == 0 //true true == 1 //true true == 2 //false undefined == 0 //false null == 0 //false "5" == 5 //true
全等和不全等
- 不转换直接比较 === !==
"55" == 55 //true
"55" === 55 //false
"55" != 55 //false
"55" !== 55 //true
3.5.8 条件操作符 ?
var max = (num1 > num2)?num1:num2
3.5.9 赋值操作符 =
var num = 10
- 复合赋值操作符
*=
/=
%=
+=
-=
<<=
>>=
>>>=
3.5.10 逗号操作符
var num1=1, num2=2, num3=3;
var num = (1,2,3,4); //4