我啃犀牛书的日子(一)
一、词法结构
Javascript是用Unicode字符集编写的
1.区分大小写
关键字的大小写不能改变
同一个词各个字母大小写不同,那就是不同的变量:Hello hello hellO HeLLo是4个不同变量
2.空格、换行符、格式控制符
JS会忽略程序中标识之间的空格;忽略换行。
普通空格符\u0020
水平制表符\u0009
垂直制表符\u000B
换页符 \u000C
不中断空白\u00A0
字节序标记\uFEFF
将以下字符识别为行结束:
换行符 \u000A
回车符 \u000D
段分隔符\u2028
行分隔符\u2029
3.Unicode转义序列
使用任意6位ASCII来代表任意16位Unicode内码。格式:\u_ _ _ _ ,由\u为前缀,后接4个十六进制数。
可用于字符串直接量,正则表达式直接量和标识符(关键字除外)
在注释中将不会被解析
4、注释:2、3不能嵌套
1.// 单行注释
2./* 多行注释 */
3./*
* 文档注释:用于说明此文档的作用
*/
5、直接量(literal):可以在程序中直接使用的数据值
1.数字,小数 123,1.23
2.字符串 "hello" , 'hello'
3.布尔值 ture , flase
4.正则表达式直接量 / script /gi
5.null
6.对象 { }
7.数组 [ ]
6、标识符 和 保留字
标识符:用于命名 变量 和 函数 或者 标记循环中需要跳转的特定位置
标识符的首字符只能用 1.字母 2._ 下划线 3.$美元符号
保留字:
7、分号
意味着语句的结束;若不加,程序将在换行处自行添加,若无法解析则不添加,直到能够解析的换行处添加。
二、类型、值、变量
js不区分整型和浮点型,所有数字都是以浮点数表示。可以在程序中直接使用的数字是直接量,另外,像-2这种负值是一元求反运算,不是直接量。
js能表示的最大值为 ± 1.7976931348623157 × 10308
js能表示的最小值为 ± 5 x 10-324
1.1 整型直接量:
a.十进制: 0 3 9999
b.十六进制: 0xffc 0x556 (以0x为前缀,后面才是数值)
c.八进制: 0377 0234 (以0为前缀,后面是数值。ECMA标准不支持八进制,所以在严格模式下无法解析)
1.2 浮点型直接量:
a.生活中常用 3.14
b.省略0 .5 => 0.5
c.科学计数法 6.02e23 (e23 => 1023)
6.5E-15 (E => 10-15)
1.3 算数运算
a. + 加法
b. - 减法
c. * 乘法
d. / 除法
e. % 除法取余
g.内置对象Math的各种方法
h.数值结果超出js能表示的最大值(上溢),显示Infinity
i.数值结果小于js能表示的最小值(下溢),显示-Infinity
j.NaN 是 not a number 的意思。
k.NaN 和任何值都不相等,包括它本身
注:运算出现上溢、下溢、除以0浏览器不会报错;基于Infinity 和 -Infinity的运算结果还是无穷大值,且保留正负号;做数学逻辑上无法完成的运算都返回NaN。
14 .二进制浮点数和四舍五入错误
任何相差0.1的两个数字相减,得数都不等于0.1,出现了极小的偏差,称之为精准丢失;事实上还有其他情况,如0.1+0.2等等,这里不一一赘述。
其实这是设计者在创立语言的时候没考虑进去所导致的,因为JS本就不是用于精准计算的语言,它的目的是在Netscape浏览器内运行。
1.5 日期和时间
js内置Date()构造函数,用于创建表示日期和时间的对象。
2.1 文本
a.string是由16位值组成的不可变的有序序列,一般是Unicode字符集
b.string.length是“16位值”的个数
c.字符串是由单引号或双引号括起来的。eg: "hello"
d.字符串的索引值从0开始,空字符串长度为0
注:字符串中夹杂着需要显示的(而不是程序运行需要)引号时,要转义字符 \ 将其转义。
eg: "we're young" ==> "we\'re young"
在HTML结构中有时也需要用到引号,应各自使用独立的引号风格。
eg: <button onclick = "alert('Thank you')"
2.2 转义字符 含义
\o NUL字符
\b 退格符
\t 水平制表符
\n 换行符
\v 垂直制表符
\f 换页符
\r 回车符
\" 双引号
\' 撇号或双引号
\\ 反斜线
\xXX 由两位十六进制数指定的Latin-1字符
\uXXXX Unicode字符集
2.3字符串的使用
1. + 好可用于字符串拼接
2.string.length 可用用来检测字符串的长度,这是js内置的字符串对象方法。
3.字符串是固定不变的,字符串的方法只是返回新的字符串,原字符串不改变
2.4匹配模式
3. 布尔值
1:true 2:false
任意js里面的值都能被转换成布尔值,以下会被转换成false:
undefined
null
0
-0
NaN
[] 空数组
"" 空字符串
“ ” 包含空格的字符串
除了上述值,其他任何值包括对象都能被转换成true;
4. null和undefined
null是空对象,typeof(null) => object
undefined是未定义 typeof(undefined) => undefined
1.他们不包含任何属性和方法,null. ;undefined[]都会产生一个类型错误
2.在严格模式下 null 不等于 undefined
在非严格模式下 null == undefined ,但是 null === undefined 是false
5. 全局对象
解释器启动时,它将创建一个全局对象,并给它定义初始属性:
全局属性:undefined Infinity NaN
全局函数:isNaN() parseInt() eval()
构造函数:Date() RegExp() String() Object() Array()
全局对象,Math和JSON等
6.包装对象
1.字符串、数字、布尔值是直接量,它们是不可以被赋值的,可是它们又可以使用对象的方法
eg:s.length
2.这是因为创建直接量的同时,JS会通过 new String(s)的方法将其转化成对象,直接量是继承了String()对象的方法。并且这种特性在引用后销毁(对象被销毁)。
3.即使对以上3种直接量赋值也无效,因为修改只作用于临时对象,可它们被销毁了。
4.存取字符串、数字、布尔值的属性时创建的临时对象叫包装对象。
5. 假设: var s ="hello" , n = 1 , b = ture;
var S = new String("hello") , N = new number(1) , B = new Boolean(true)
s == S , n == N , b == B 是对的,
s === S , n === N , b === B 是错的。
三、类型转换
1.转换和相等性
== 比较时,会把数据类型不同的两个数据进行转换, === 则不会。
2.显示类型转换
a.
函数String() Boolean() Number() Object()在不使用new操作符时,它们是类型转换函数。
任何值都有toSring()方法,除了null undefined
对null undefined显示转换成对象,不抛出异常,而是会返回空对象。Object(null) => {}
b.运算符号的隐式转换
+ 符号两边某一个数据是字符串,+号 把另一个操作数转换成string,然后起到连接字符串的作用
- * / % 符号两边某一个数据是字符串,运算会把字符串转换成number,然后运算
! 布尔取反,将数据转换成布尔值,再逻辑取反运算
c.Number类的3个方法会将结果以字符串形式返回,3个放法都会4舍5入和补0占位。(number -> string)
toFixed()保留指定位数的小数点
toEeponential()转换成指数形式显示
toPrecision()将有效数字转换成指数形式显示
d.全局函数parseInt() parseFloat() 将包含数字的字符串转换数字的类型。(string -> number)
parseInt()只解析整数,若字符串以"0x"或"0X"开头,将被解析为16进制
parseFloat()解析整数和浮点数,
注:若第一个字符是非法空格字符则返回NaN
3.对象转换成原始值
a. OTB 对象转换成布尔值
除了:null undefined 0 -0 NaN 空字符串 包含空格的字符串,这7种情况被转换成false,其它所有对象转换成true
b. OTS toString() 把对象转换成字符串;
数组:将每个数组转化成字符串,并用逗号连接
(["1","3","5"]).toString() => "1,3,5"
函数:返回函数内的代码
正则:将其转化为直接量字符串
日期对象:返回可读的时间日期字符串
另一个转换对象的函数是valueOf(),它默认将对象转换为表示它的原始值,若无,则返回本身。
4.声明变量
a.JS属于动态语言,意味着在程序运行期间才去做数据类型的检查,可以不给数据指定数据类型。
b.访问没有赋值的变量,返回undefined
c.任何变量都应该用var声明,否则它将属于全局变量;在ES5严格模式下,读取没有声明的变量,给没有声明的变量赋值,都会报错。
d.重复声明和赋值是合法的。
e.可以在循环体for 和 for...in里面使用var声明变量
5.变量作用域
a.函数体内声明的变量是局部变量,非函数体内声明的是全局,没有使用var声明的变量也是全局
b.局部变量比全局变量具有更高的优先级,若重名,全局被遮盖。
6.函数作用域
函数体都有自己的作用域,{ } 内的代码段外部是不可见的,但是函数可以使用外部的变量。
7.声明提前
变量可以在声明前就使用,但此时它并没有被初始化。
eg: console.log(a);
var a = "1";
程序输出的结果为undefined,其在程序中的表现等同于:
var a;
console.log(a);
a = "1";
8.作为属性的变量
a.全局中使用var 声明变量,此变量不可用delete删除
b.全局中不使用var声明,此变量可删除
9.作用域链
eg: var x = "hello"
function parent(){
function son(){ return x;}
return son();
}
parent(); // => 输出 "hello"
在这个例子中,作用域链上有3个对象:全局对象、外部函数parent、内部函数son。当JS需要查找x时,这 个过程称为变量解析;那么JS会从作用域链上的第一个对象,也就是son()对象开始查找,若无,则在上一级查 找,直到全局还找不到,则抛出一个引用错误("x is not defined(...)")。
一般函数:
a.定义一个函数时,它将保存一个作用域链(第2行)
b.调用时,创建一个新对象来存储它的局部变量(第6行运行时,第4 5行被保存在一个新对象上)
c.将这个对象添加至函数保存的作用域链上
嵌套函数:
a.与一般函数的行为一致
b.每次调用外部函数parent()时,内部函数son()都会被重新定义,每个son()的作用域链都是不同的