一、ECMAScript与JavaScript
ECMAScript是JavaScript的语言标准。通常而言,被用来表达相同的含义,但是Javascript的含义实际上要更广一些。一个完整的Javascript实现包含:
- ECMAScript
- DOM(文档对象模型)
- BOM(浏览器对象模型)
二、关于 <script>
在HTML文档中嵌入Javascript代码,采用<script>
标签来嵌入脚本。script标签有下列常用的属性:
async
如<script src="xx.js" async="async"></script>
,表示立即下载脚本,但是并不是马上执行,而是异步执行(可以跳过执行脚本继续解析HTML文档)defer
表示立即下载脚本,但是需要在文档完全解析完成
后才开始执行src
指定引用外部JavaScript代码文件的URL,如果指定了该属性,则包含在<script></script>标签之间的代码会被忽略
1、浏览器解析文档的规则
浏览器会从头到尾解析HTML文档,如果遇到<script>
标签,则会先暂停对其他内容的解析,而先执行script标签中的代码。如果没有指定defer
和async
属性,那么浏览器会按<script>
标签出现的顺序解析,上一个解析完了才解析下一个。
所以,因为浏览器的这种规则,对于script标签,放在文档的后面,可以避免因为解析执行js代码带来的延迟问题
注意: 对于内嵌代码的script标签,defer和async属性是无效的
2、async和defer的区别
两者都可以延迟脚本的执行。但是defer是在HTML文档加载完毕后执行,而async则是异步执行,即解析的时候会先跳过继续往下执行,等到一定的时机时再执行,使用async的时候,不要在加载期间修改DOM
3、script中嵌入代码与引用外部js文件的区别
相比直接在script标签中嵌入代码,引用外部js文件具有以下的好处:
- 可维护性:js代码与HTML文档分离,便于维护,且方便复用
- 可缓存:如果有多个HTML页面引用同一个js文件,那么js文件只需要下载一次
- 适应未来:无需使用XHTML中针对内嵌代码的注释、hack方法,使得XHTML和HTML中使用JS的用法是一致的
三、文档模式
文档模式,有
- 混杂模式(Quirks Mode)
- 标准模式(Standards Mode)
- 准标准模式(Almost Standards Mode)
这些模式会影响CSS的呈现,也会在某些情况下影响JS的解释执行。HTML5中开启标准模式的方法:<!doctype html>
四、Javascript中的关键字和保留字
Javascript中的关键字主要有:
- 流程:if、else、switch、case、break、default
- 函数:function、return
- 循环:do、while、for、continue
- 变量:var
- 对象:this、typeof、instanceof、delete、in、with
- 错误:try、catch、finally、throw
- 其他:void、debugger
Javascript中的保留字主要有:
- 面向对象:class、interface、static、super、extends、implements、abstract、private、public、protected
- 数据类型:int、short、boolean、byte、long、char、float、double
- 限定符号:const、final
- 模块管理:import、export
- 流程相关:goto
- 线程相关:synchronized、transient、volatile
- 其他:native、enum
注意:ES5中规定关键字和保留字虽然不能作为变量标识符,但是可以作为对象的属性名。但是一般不推荐使用关键字和保留字作为属性名和变量名,此外,ES5限制严格模式下eval
和arguments
也不能用作标识符和属性名
五、数据类型
Javascript中的数据类型主要有:
- 原始类型:number、boolean、string、null、undefined
- 引用类型:object
1、typeof
typeof可以用来检测给定变量的数据类型:
typeof 123; // number
typeof true; // boolean
typeof "Hello"; // string
typeof {}; // object
typeof []; // object
typeof null; // object
typeof undefined; // undefined
typeof Math.max; // function
typeof x; // 变量x是一个未定义的变量,返回undefined
2、undefined和null
undefined
和null
是两个特殊的类型,这两个特殊的类型,各自都只有一个值。
关于undefined
:
1、当一个变量声明了未赋值的时候,这个变量的值就是undefined
2、当函数定义了参数,但是参数没有传入值的时候,参数的值就是undefined
3、一个变量没有声明就使用,和一个变量声明了没使用,使用typeof都是得到undefined,但是没有声明就使用的话,则会报错
关于null
:
1、null主要用来表示空指针对象,当一个变量打算将来用来保存变量的时候,初始值宜设为null
2、标准规定undefined == null
返回true
3、boolean类型
1、转化规则:
- 返回false的情形:false、0、”、NaN、null、undefined
- 除了上述情况,其他情况下都返回true
2、可以使用!!
来强制转化为boolean类型
4、number类型
1、JS中采用IEEE754格式来表示整数和浮点数
2、几种进制的表示:
55; // 十进制
077;// 八进制,但是这种字面量在严格模式下无效,会报错。
088;// 十进制,因为0后面跟着的不是0~7的数,所以前导0会被忽略
0xF;// 十六进制
3、浮点数的表示
- 如果小数点后跟着的0的个数>=6个,则会转为科学计数法表示,如:
0.000001
是表示为0.000001
,0.0000001
则表示为1e-7
- 类似于
0.1 + 0.2 == 0.3
会返回false,这是IEEE754格式计算的通病
4、JS中可以表示的数值范围为Number.MIN_VALUE ~ Number.MAX_VALUE
,如果超过这个范围,则会表示为-Infinity
或者Infinity
,如果要测试一个数是否是有穷
的,可以使用isFinite()
函数来判断
5、NaN是一个特殊的number类型的值,它表示Not a Number,而且,NaN
是不等于本身的,即NaN == NaN
是返回false的。可以用isNaN()
来判断
6、number数值转化规则:
Number("Hello, World"); // NaN
Number(""); // 0
Number("00011"); // 11
Number(true); // 1
Number(undefined); // NaN
Number(null); // 0
对于字符串,遵守以下规则:
- 只包含数字的情况下,会转为十进制数值。如果包含的是有效的浮点数值如
1.1
,则转为对于的浮点数;如果有前导0的话,都会被忽略 - 如果包含的是十六进制的字符串,如
0xf
,则会转为相应的十进制数值 - 如果是空串,如
''
,会转为0 - 除上述外的,都转为NaN
7、如果是对象的话,则先调用valueOf()
方法再转化,若仍然返回NaN,则再调用toString()
方法
8、使用parseInt()
进行更灵活的转化,如parseInt('123aaa')
返回123
,而Number('123aaa')
返回NaN
。此外,parseInt()
可以 传入第二个参数,用于表示要转化的进制
10、使用parseFloat()
进行浮点数的转化,该函数只接受10进制数,对于非10进制数,一律转为0。
5、string类型
1、string类型是由0至多个16位Unicode字符组成的字符序列,即字符串。字符串用''
或者""
包围(和PHP不同,JS中这两种表示是等效的)
2、\xnn
以十六进制代码nn表示一个字符,而\xnnnn
以十六进制代码nnnn表示一个Unicode字符(这种表示下,算1个字符)
3、string是不可变的,所以一经创建,值便不可改变。如果要改变值,则需要销毁原来的字符串,再创建新的字符串
4、除了null
和underfined
,其他的类型都可以调用toString()
方法来转化为字符串。toString()
方法接受一个参数,表示要输出的进制。如:
var num = 25;
num.toString(16); // 输出19
5、String
构造函数也可以进行类型转化。而且比toString()
更灵活的是,它还可以转化underfiend
和null
,如:
String(123); // "123"
String(null) // "null"
String(undefined); // "undefined"
String(false); // "false"
String(true); //"true"
6、String构造函数执行以下的规则:
- 如果值有
toString()
方法,则调用该函数的输出结果 - 如果值为
null
或者undefined
,则返回"null"
或者"undefined"
7、可以使用形如123 + ''
的形式,强行转化为字符串
6、object类型
创建Object类型实例的方式为:
var o = new Object()
,在不传给构造函数参数的情况下,可以省略圆括号,如:var o = new Object;
Javascript中的一切对象(除了宿主对象外,都继承自Object类),Object的每个实例均有以下方法:
constructor
保存着用于创造当前对象的构造函数hasOwnProperty(propertyName)
判断当前实例本身是否有属性propertyName
(而不是在原型链上有)obj1.someisPrototypeOf(obj2)
用于检查obj1是否是obj2的原型propertyIsEnumerable(propertyName)
检查某个属性是否可枚举(如果可以枚举,则可以用for-in
来枚举出来),如[1, 2, 3].propertyIsEnumerable('length')
返回的是false
toLocaleString()
返回对象的字符串表示,字符串与执行环境的地区对应toString()
返回对象的字符串表示valueOf()
返回对象的字符串、数值或者布尔值表示
六、操作符
1、+
、-
、++
、--
这些操作符,会先将操作对象转化为number类型,再执行操作
2、任意类型+
一个字符串,转为结果为string类型
3、使用&&
或者||
这两个逻辑运算符的时候,具有短路特性
。而且如果两个操作数中有一个不是布尔值,那么逻辑操作就不一定返回布尔值,如:
1 && 2; // 返回 2
1 || 2; // 返回 1
[1, 2, 3] || true; // 返回[1, 2, 3]
true && [1, 2, 3]; // 返回[1, 2, 3]
4、在关系运算中,如果比较对象有一个为数值,一个不为数值,则另一个不为数值的对象会被转为数值。如:
'23' < 3; // false,'23'会被转为23,再与3比较
'a' < 3; // false,'a'会被转为NaN,任何操作数与NaN进行关系比较,结果都是false
5、==
与===
1)对于==
,执行的是“相等”比较,会先进行类型转换再比较。不相等用!=
2)对于===
,执行的是“全等”比较,直接进行比较,不会转换。不全等用!==
七、函数
1、JavaScript中,不要求函数定义时的参数个数和实际传入的时候要一致。即JS中是没有函数签名这种限制的
2、函数内部有一个arguments
对象,它类似于数组(使用下标0~n调用,有length属性),但是不是数组(所谓的Array-Like Object)
3、arguments
的值是和参数保持同步的,即:
function fn(a, b) {
a = 5;
console.log(arguments[0]);
}
fn(1); // 输出 5
但是,这并不代表访问两个值读取的是同一内存单元
,事实上,它们的内存单元是独立的,仅仅只是值保持同步。类似于例子中的a
参数和b
参数,被称为命名参数
,没有传递值的命名参数,默认值是undefined
注意:在严格模式下,arguments的值不会和命名参数保持同步
4、JavaScript中是没有重载的,如果要实现重载,则可以通过arguments
参数进行模拟