一、写在前面
最近重读《JavaScript高级程序设计》,总结下来,查漏补缺。
二、JS简介
2.1 JS组成
- ECMAscript:以ECMA-262为基础的语言,由浏览器支持
- DOM:编程接口(API), 将页面映射成节点结构(文档树),提供操作方法
- BOM:浏览器对象模型,处理浏览器窗口和框架交互(部分扩展)
2.2 <script>
- 实现在HTML中插入JS
- 内嵌,外联(好处:可维护,可缓存,适应未来)
- 推荐放在body中、内容后,缩短内容呈现时间(浏览器遇到body呈现内容)
参数:
-
async: 立即下载脚本(外部文件),异步执行
- 不保证按出现顺序执行
- 多个async时,保证互不依赖,建议无修改DOM操作
- 在页面load前执行,不一定在DOMContentLoaded事件触发前执行
- charset: 指定代码字符集(很少用,部分浏览器忽略该参数)
-
defer: 下载后延迟执行,文档完全解析显示后执行
- 延迟脚本,延迟到</html>后执行,页面load前执行
- 最好只有一个延迟脚本(HTML5要求按出现顺序执行,但实际不一定按顺序执行,也不一定会在DOMContentLoaded事件触发前执行)
- language: 标明编写语言(废弃)
-
src: 外部文件及地址链接
- src、标签间嵌入内容同时存在,src下载执行,嵌入内容不被解析
-
type: 标明内容类型(MIME类型),默认text/javascript
- 其他application/x-javascript,application/javascript,application/ecmascript
2.3 文档模式
- 混杂模式
- 标准模式
2.4 <noscript>
早期浏览器不支持脚本/脚本被禁用时显示,使用noscript平稳退化
<body>
<noscript>您的浏览器不支持脚本/脚本被禁用</noscript>
</body>
2.5 PS:
1. async和defer区别?
蓝色线代表网络读取,红色线代表执行时间,均针对脚本;绿色线代表 HTML 解析。
- 默认,同步,顺序解析,解析到立即加载,加载完立即执行。
- defer,异步,同时加载,html解析完成后执行(多个,不一定按顺序执行,适用外链脚本)(HTML5要求按出现顺序执行,但实际不一定,不一定会在DOMContentLoaded事件触发前执行)
- async,异步,同时加载,加载完立即执行(多个,乱序执行)
2. XHTML和HTML主要不同?
- 元素必正确嵌套,防止<a><b></a></b>
- 单标签< />、双标签<> </>闭合
- 标签名、属性大小写敏感
- 必须有根元素
三、基本概念
3.1 ECMAScript语法
区分大小写
-
标识符:
- 参数,变量,属性,函数名
- 以字母、下划线_、$开头
- 惯例为驼峰
- 名称不能为关键字
-
注释:
- 单行注释 / /
- 块级注释 /* */
- 严格模式: 编译指示" user strict "
-
语句:
- 推荐以分号;结尾
- if( ) 可省略代码块{ }直接书写语句,但推荐不省略
-
关键字:
- break case catch continue debugger default delete
- do else finally for function if in
- instanceof new return switch this throw try
- typeof var void while with
-
保留字:
- abstract boolean byte char class const debugger double
- enum export extends final float goto implements import
- int interface long native package private protected public
- short static super synchronized throws transient volatile
- 外加let、yield、eval、arguments
3.2数据类型
变量:松散类型(可修改值的类型),var创建时有作用域
- 只定义未初始化,值为undefined
- 不推荐在局部中定义全局变量
数据类型:
- 简单(基本)数据类型:number,string,Boolean,undef,null
- 复杂数据类型:Object
typeof操作符:
- 值:number,string,boolean,undefined,null,object,function
- 特殊情况: typeof null ---> object 被认为是空对象指针
对象:
- 空对象,初始化时obj = null 通过 obj != null 来看是否保存对象引用
- 新建对象:new Object( ) 或 new Object
布尔:
- true false 区分大小写
数值:
- 八进制(严格模式下失效),0开头,后续值超过7则 079无效,解析为79
- 十六进制,不区分大小写,0x开头欧,后续0-9、A-F
- 科学计数法,123e7或123e-7,浮点数最大精度17位小数
- 浮点数进行计算,结果不准确
- 数值范围Number.MIN_VALUE 5e-324 ~ Number.MAX_VALUE 1.7976931348623157e+308,超出对应±infinity
- NaN,返回不为数值,也为数值类型,不影响代码执行,操作NaN都返回NaN,与任何值都不相等
字符串:
- 0或多个16位unicode字符组成
- 单双引号无区别
- 字符字面量:\n \t \b \r \f \\ \' \" \x \u 及6位unicode字符
- 一旦创建,值不可改变,只能---->新的创建,销毁原来的(旧版浏览器执行速度慢)
3.3 方法
数值
- isNaN( )隐式转换数值
- Number( ),null ----> 0,undefined ---> NaN,八进制前导0失效,十六进制转换为十进制整数
- parseInt( ),直到不是数字,保留整数,识别八进制、十六进制,可指定第二个参数parseInt(a,8)指定八进制
- parseFloat( ),不解析前导0,可用于:科学计数法转完全展示
字符串:
- toString(a) 参数可设置进制,数据转换值,有些不能转换(undefined,null)
- String()遵循先按toString执行,不成功再按String()转换(undefined----> undefined , null ----> null )
对象:
- constructor 创建实例的函数(构造函数)
- hansOwnProperty 检查当前对象中存在某属性(不查原型)
- isPrototypeOf 检查是否是某对象的原型
- propertyIsEnumerable 能否使用for-in枚举
- toLocaleString 返回对象字符串表示
- toString( ) 对象的字符串表示
- valueOf( ) 返回对象的字符串、数值或布尔值
3.3 操作符
算数、位、关系、相等操作符
一元操作符(隐式转换):
- 只能操作一个值
- 前置(副效应:语句被求值前值改变)
- 后置(语句被求值后值改变)
- 含对象,执行valueOf( ) 后得到的值进行加减
位操作符:
- 转换为32位整数,31位二进制数+ 1位符号位(0正1负)
- 按位非 ~ 得到值的负值 - 1(底层操作,比 - a - 1 快)
- 按位与 & 二进制每位相与得出二进制值
- 按位或 | 二进制每位相或得出二进制值
- 按位异或^ 两位相异则为1,否则为0
- 左移 << 移动后补0,不影响符号位
- 右移 >> 保留符号位,移动后补0
- 无符号右移 >>> 不保留符号位,负数一般右移后很大
布尔操作符:
- 非 !
- 与 && 短路操作(有 false 则不往下执行),null 返回null,NaN返回NaN ,undefined返回undefined
- 或 || 短路操作(有true 则不往下执行 )
乘性操作符:
- 隐式转换为数值后计算,/ 除法 ,% 取余
加性操作符:
- + 加法, - 减法
关系操作符:
- < 、 >、 <=、 >=
- 都为字符串时,比较字符串字符编码值
- 有对象,转valueOf( ),不成则toString( )
- 字符串比较,大写小于小写,如需比较可全转小写
- 都为字符串的数字,则按编码比
- 一个数字一个字符串,会转为数值
- 转换出NaN,则结果false
相等操作符:
- 强制转换规则:有布尔转为数值、有数有字符串转为数值
- 只有一个对象,按照valueOf()转换后比较
- null == undefined,null !== undefined
- 两个对象,比较是否指向同一对象
条件操作符:条件?‘真,取值’:‘假,取值’
赋值操作符:
- =、 +=、 *=、 /=、 %=、 <<=、 >>=、 >>>=(简化书写,不影响性能)
逗号操作符:
- 分隔多个操作
- a =(1,2,3,4),a值为最后一个4
3.4 PS:
1. valueOf与toString
2. 负数的二进制表示:
- 绝对值的二进制码,按位取反,加1,得到
3. 按位非运算符 ~
function fast() {
let s = 2222222222;
let start1 = Date.now();
for (var i = 1; i<10000000000;i++) { s = ~ s };
console.log('fast',Date.now() - start1);
};
function slow() {
let s = 2222222222;
let start2 = Date.now();
for (var i = 1; i<10000000000;i++) { s = - (s + 1) };
console.log('slow',Date.now() - start2);
};
fast();
slow();
相差4-5秒左右,底层运算更快
4. && || 操作
let d = { name: 'aa' } ,??代表某参数
- d && ?? 返回??
- ?? && d ??为true返回d,否则返回??
- 有null NaN undefined 返回 对应null NaN undefined
- d || ?? 返回 d
- ?? || d ??为false返回d
- d || e 返回 d
- 都是null NaN undefined 返回 对应null NaN undefined
3.5 语句
- if (条件) { 代码块 }
- do-while 后测试循环语句,while中满足则执行
- while 前测试循环语句
- for :while做不到,for也做不到、for( ; ; )三参数可选
- for-in 循环对象属性,顺序不可预测
- label 名字:语句,结合for循环,方便continue 名字 执行该操作,break 名字 中断名字操作
- break continue
- with 将代码作用域设置到特定对象中,影响性能,不建议使用
with(location) {
var t = search.name;
var w = hostname;
}
// 等同于
var t = location.seatch.name;
var w = location.hostname;
- switch 全等比较(不进行类型转换),可以合并情况,case可为变量、表达式,
switch (i) {
case 25:
/* 合并两种情形 */
case 35:
alert("25 or 35");
break;
...
}
3.6 函数
function (参数) {函数体}
- 定义的参数个数可以≠传入参数个数,适用传参个数不定执行不同操作
- 可function acc(a)传acc( ) 或function acc()传acc(1,2)
- 内部可用arguments来访问参数,如果a对应arguments[0],两值内存空间独立,但互相同步
- 没有重载:函数没有签名,同名函数后定义的生效
读取这两个值会访问相同的内存空间;它们的内存空间是独立的,但它们的值会同步。但这种影响是单向的:修改命名参数不会改变arguments中对应的值。另外还要记住,如果只传入了一个参数,那么为arguments[1]设置的值不会反应到命名参数中。这是因为arguments对象的长度是由传入的参数个数决定的,不是由定义函数时的命名参数的个数决定的。
书中:修改命名参数不会改变arguments中对应的值。 实际改变arguments[0]会同步a ,改变a也会同步argumenets[0]
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。