第一章、历史及发展
Netscape/Mozilla V.S Microsoft
1. ECMAScript
a. ES3 (1999) : 标志这成为一门编程语言。regex, 控制语句,异常等
b. ES4 (2000) : ES6 的前身,POO,强类型,数据结构,真是类和经典继承
但由于这个版本太过超前暂时被"和谐"了,被3.1替换。
c. ES5 (2009) : JSON+严格模式
d. ES6 (2013草案/ 2015正式) : 环境(webpack+gulp)、内置对象、异步
2. DOM
a. 1级: Core + HTML
b. 2级: Views, Events, Style, Traversal and Range
3. BOM
Window, navigator, location, screen, cookies, XMLHttpRequest
第二章、HTML中的JS
<script>的5个属性:async, charset, defer, src, type
src: 外部js文件并不限制扩展名,所以使得一些服务器端语言可以动态生成js代码,比如JSP、PHP。
type: 表示编写代码使用的脚本语言的内容类型,也称为MIME类型。
加载通常是阻塞的!可以通过defer和async来解决
defer 延迟脚本:直到整个页面都解析完毕后再运行,但先于DOMContentLoaded事件,并且多个脚本会按照顺序执行。
*放在<body/>之前是最佳选择
async异步脚本:立即开始加载脚本,异步不阻塞页面加载。先于页面得load事件执行。确保多个脚本之间互相独立,不对DOM进行操作。
第三章、基本概念
大小写敏感,驼峰,严格模式“use strict”;变量类型松散
数据类型
typeof操作符:用于判断基本类型
“undefined”、“boolean”、“string”、“number”、“object”、“function”
* typeof null //object”,一些老版本是会返回”function”
null 值表示一个空对象指针。用于存对象的变量还没存的时候,就应该赋值null
* if(car) //TODO
* undefined值是派生自null的, null == undefined // true
boolean
转换为false的情况 null、undefined、“”、0+NaN
Number类型
进制字面值:八进制0XXX(严格和ES5下无用),十六进制0xXXX
float值:e科学计数法,精度6-17位
精度问题:0.1+0.2==0.3 //false 所有使用IEEE754数值格式得语言的通病
1) 扩大倍数法:
2) 四舍五入法:parseFloat((0.1+0.2).toFixed(2)) === 0.30 || Math.round()
数值转换:parseInt(“string”, 进制基数);parseFloat(); Number()
*正负零相等,Number.MIN_VALUE, Number,MAX_VALUE isFinite()函数
NaN:
1) 任何涉及NaN的运算结果返回都是NaN。
2) 任何涉及NaN的操作结果返回都是false。
3) NaN和任何值都不相等,包括本身
Object类型:主要属性、方法、
constructor()
hasOwnProperty(“propertyName”)
propertyIsEnumerable(“propertyName”)
isPrototypeOf(object) 检查原型
toString() 返回字符串表示
valueOf() 返回字符串、数值、或者布尔表示,通常和toString()的返回值相同
操作符
一元前置、后置操作符
var a=2,b=20;
var c= a-- + b; // 22
var c= a + b; // 21
位操作符,本质32位二进制数
正数,普通二进制; 负数,二进制求反+1
ex:
25: 0000 0000 0000 0000 0000 0000 0001 1001
3: 0000 0000 0000 0000 0000 0000 0000 0011
1) 位非NOT: ~25=-26;
2) 位与AND:25&3 = 1;
3) 位或OR:25|3 =27
4) 位异或XOR: 25^3=26 // 1和0出1
布尔操作符 (略)
全等操作符 (略)
“55”==55 //true,先会做一次转换
“55”===55 //false
函数
ECMAScript解析器不在乎函数传参类型,个数。全部放在arguments这个对象里
对arguments对象操作像,但并不是数组对象。arguments[0], arguments.length
*没有传统意义的重载,但是比可以根据参数类型和数量来模仿出重载
第四章、变量,作用域和内存
变量
基本类型:Undefined、Null、 Boolean、Number、 String、Symbol。直接访问内存数据段
引用类型:Object,引申function,Array 访问的时候是引用
当复制的时候,操作的是引用,即浅拷贝。
当添加属性的时候,操作的是实际对象
传参的时候,是向arguments对象传内存地址。
typeof操作符:用于判断基本类型
instanceof操作符:用于判断引用类型的类型。本质是根据原型链判断
比如Object, Array, RegExp
执行环境及作用域
全局执行环境根据ECMAScript执行的宿主环境来决定,web当中就是window对象,因此所有全局变量和函数都是作为window对象的属性和方法创建的。
当执行环境中的所有代码执行完毕后,该环境将会被销毁。如果是全局执行环境直到应用程序退出,例如关闭网页等。才会被销毁
执行环境(execution context)
作用域链(scope chain) 虽然_局部变量访问要比 全局变量要快, JS引擎在优化标识符查询方面非常优秀,所以几乎可以忽略不计。
内存
GC垃圾回收机制
按照固定的时间间隔,找出哪些不再继续使用的变量,然后释放内存。
标记清除策略(mark-and-sweep) - 主流沿用至今
变量进入环境就tagged with mark
变量离开环境就tagged with sweep
引用计数(reference counting) - 已废弃
值/内存被其他变量引用,则引用计数+1。
如果对应的变量,指向了其他值,那么这个值/内存的引用计数-1。
问题是当出现循环引用的时候,objA的属性是objB,objB的属性是objA。跳出作用域了之后应该被回收,但是这两个对象引用计数永远是2。多次调用这个函数,内存释放不了会溢出。
GC的性能问题
IE7之前声名狼藉的GC性能问题,达到阀值就会运行。就导致在脚本生命周期内可能会频繁触发GC。
作为开发者,并不需要手动去释放内存,要做的而是解除引用(dereferencing),把变量赋值为null,即解除变量和值/内存之间的引用,或者说脱离执行环境。让下次GC运行时自动回收。